How do you take a pre-existing dictionary and essentially add an item from a list into the dictionary as a tuple using a for loop? I made this example below. I want to take color_dict and reformat it so that each item would be in the format 'R':['red',1].
I got as far as below, but then couldn't figure out how to do the last part.
lista = {'red':'R', 'orange':'O', 'yellow':'Y', 'green':'G',
'blue':'B', 'indigo':'I', 'violet':'V'}
color_dict = {'R':1, 'O':2, 'Y':3, 'G':4, 'B':5, 'I':6, 'V':7}
a = color_dict.keys()
color_keys = []
color_vals = []
for x in lista[0::2]:
color_keys.append(x)
for x in lista[1::2]:
color_vals.append(x)
new = zip(color_keys, color_vals)
new_dict = dict(new)
print new_dict
If anyone has any other suggestions that would be great, I'm not understanding how to use dict comprehension.
Basically what you want to do is to loop through the items in lista and for each pair color: colkey find the respective value in color_dict (indexed by colkey). And then you just need to stitch everything together: colkey: [color, color_dict[colkey]] is the new item in the new dict for each item in the lista dict.
You can use a dict comprehension to build this:
>>> new_dict = {colkey: [color, color_dict[colkey]] for color, colkey in lista.items()}
>>> new_dict
{'O': ['orange', 2], 'Y': ['yellow', 3], 'V': ['violet', 7], 'R': ['red', 1], 'G': ['green', 4], 'B': ['blue', 5], 'I': ['indigo', 6]}
Related
Let's suppose I have the following list made out of lists
list1 = [['a','b'],['a'],['b','c'],['c','d'],['b'], ['a','d']]
I am wondering if there is a way to convert every element of list1 in a dictionary where all the new dictionaries will use the same key. E.g: if ['a']
gets to be {'a':1}, and ['b'] gets to be {'b':2}, I would like for all keys a the value of 1 and for all keys b the value of 2. Therefore, when creating the dictionary of ['a','b'], I would like to turn into {'a':1, 'b':2}.
What I have found so far are ways to create a dictionary out of lists of lists but using the first element as the key and the rest of the list as the value:
Please note that's not what I am interested in.
The result I would want to obtain from list1 is something like:
dict_list1 = [{'a':1,'b':2}, {'a':1}, {'b':2,'c':3}, {'c':3,'d':4}, {'b':2}, {'a':1,'d':4}]
I am not that interested in the items being that numbers but in the numbers being the same for each different key.
You need to declare your mapping first:
mapping = dict(a=1, b=2, c=3, d=4)
Then, you can just use dict comprehension:
[{e: mapping[e] for e in li} for li in list1]
# [{'a': 1, 'b': 2}, {'a': 1}, {'b': 2, 'c': 3}, {'c': 3, 'd': 4}, {'b': 2}, {'a': 1, 'd': 4}]
Using chain and OrderedDict you can do auto mapping
from itertools import chain
from collections import OrderedDict
list1 = [['a','b'],['a'],['b','c'],['c','d'],['b'], ['a','d']]
# do flat list for auto index
flat_list = list(chain(*list1))
# remove duplicates
flat_list = list(OrderedDict.fromkeys(flat_list))
mapping = {x:flat_list.index(x)+1 for x in set(flat_list)}
[{e: mapping[e] for e in li} for li in list1]
Here a try with ord() also it will work for both capital and lower letters :
[{e: ord(e)%32 for e in li} for li in list1]
I am trying to write a part of program where the user inputs a Target Word (targetWord = input()), assigns a nested Dictionary with the key being the same as the input word.
For example:
mainDict = {
'x': {'one': 1, 'blue': 1, 'green' :1},
'y': {'red': 1, 'blue': 2, 'two': 1},
'z': {'one': 1, 'green': 1, 'red': 1}
}
where all the values in the nested dictionary are assigned integers.
The user may input 'x', to which the program will assign:
targetDict = mainDict['x']
The program should then allow the user to input words again, but this time every single word from input is appended to a lookup list, for example user inputs 'y', then 'z':
lookup = ['y', 'z']
Then the program should run through the nested dictionary and for every value with the corresponding key as in the targetDict, append just values to a new nested list and add whatever value the nested Dictionary values are. So the output of this section should be:
targetOutput = [[2], [1, 1]]
because in nested dict 'y', only 'blue' was a common key, to which its value 2 was put in a list, then appended onto targetOutput. The same case with dict 'z', where the keys 'one' and 'green' were present in both 'x' and 'z', putting their values, 1 and 1 into a nested list.
Here is a representation of the dysfunctional code I have for:
targetOutput = []
targetDict = mainDict[targetWord]
for tkey in targetDict:
tt = []
for word in lookup:
for wkey in primaryDict[word]:
if tkey == wkey:
tt.append(targetDict[tkey])
tl.append(sum(tt))
print((pl))
The sum function at the end is because my actually final output should be the sum of the values in the nested list, akin to:
tl = [[2], [2]]
I am also trying to make the reverse happen, where in another list for every key in the lookup, it returns a nested list containing the sum of every value the targetWord dictionary also has a key for, like:
ll = [[2], [2]]
My question is, how do I fix my code so that it outputs the 2 above lists? I'm quite new with dictionaries.
The .keys() method on a dictionary gives you a dictionary view, which can act like a set. This means you can take the intersection between the key views of two dictionaries! You want the intersection between the inital targetDict and the dictionaries named in lookup:
for word in lookup:
other_dict = mainDict[word]
common_keys = targetDict.keys() & other_dict
targetOutput.append([other_dict[common] for common in common_keys])
The targetDict.keys() & other_dict expression produces the intersection here:
>>> mainDict = {
... 'x': {'one': 1, 'blue': 1, 'green' :1},
... 'y': {'red': 1, 'blue': 2, 'two': 1},
... 'z': {'one': 1, 'green': 1, 'red': 1}
... }
>>> targetDict = mainDict['x']
>>> targetDict.keys() & mainDict['y']
{'blue'}
>>> targetDict.keys() & mainDict['z']
{'green', 'one'}
The [other_dict[common] for common in common_keys] list comprehension takes those keys and looks up the values for them from the other dictionary.
If you want to sum the values, just pass the same sequence of values to the sum() function:
for word in lookup:
other_dict = mainDict[word]
common_keys = targetDict.keys() & other_dict
summed_values = sum(other_dict[common] for common in common_keys)
targetOutput.append(summed_values)
There is no point in wrapping the summed values in another list there as there is only ever going to be a single sum. The above gives you a targetOutput list with [2, 2], not [[2], [2]].
I feel like it is something basic but somehow I don't get it. I would like to loop over a list and append all the persons to the same id. Or write to the file, it doesn't matter.
[1, 'Smith']
[1, 'Black']
[1, 'Mueller']
[2, 'Green']
[2, 'Adams']
[1; 'Smith', 'Black', 'Mueller']
[2; 'Green', 'Adams']
First I have created a list of all ids and then a I had two for-loops like this:
final_doc = []
for id in all_ids:
persons = []
for line in doc:
if line[0] == id:
persons.append(line[1])
final_doc.append(id, persons)
It takes ages. I was trying to create a dictionary with ids and then combine it somehow, but the dictionary was taking the same id only once (may be I did there something not as I should have). Now I am thinking about using while-loop. While id is still the same append persons. But it is easy to understand how to do it if it has to be, for example, while id is less than 25. But in the case "while it is the same" I am not sure what to do. Any ideas are very appreciated.
You can group them together in a dictionary.
Given
lists = [[1, 'Smith'],
[1, 'Black'],
[1, 'Mueller'],
[2, 'Green'],
[2, 'Adams'] ]
do
d = {}
for person_id, name in lists:
d.setdefault(person_id, []).append(name)
d now contains
{1: ['Smith', 'Black', 'Mueller'], 2: ['Green', 'Adams']}
Note:
d.setdefault(person_id, []).append(name)
is a shortcut for
if person_id not in d:
d[person_id] = []
d[person_id].append(name)
If you prefer your answer to be a list of lists with the person_id as the first item in the list (as implied in your question), change code to
d = {}
for person_id, name in lists:
d.setdefault(person_id, [person_id]).append(name) # note [person_id] default
result = list(d.values()) # omit call to list if on Python 2.x
result contains
[[1, 'Smith', 'Black', 'Mueller'], [2, 'Green', 'Adams']]
I am new to Python. Suppose i have the following list of dictionaries:
mydictList= [{'a':1,'b':2,'c':3},{'a':2,'b':2,'c':4},{'a':2,'b':3,'c':4}]
From the above list, i want to remove dictionaries with same value of key b. So the resultant list should be:
mydictList = [{'a':1,'b':2,'c':3},{'a':2,'b':3,'c':4}]
You can create a new dictionary based on the value of b, iterating the mydictList backwards (since you want to retain the first value of b), and get only the values in the dictionary, like this
>>> {item['b'] : item for item in reversed(mydictList)}.values()
[{'a': 1, 'c': 3, 'b': 2}, {'a': 2, 'c': 4, 'b': 3}]
If you are using Python 3.x, you might want to use list function over the dictionary values, like this
>>> list({item['b'] : item for item in reversed(mydictList)}.values())
Note: This solution may not maintain the order of the dictionaries.
First, sort the list by b-values (Python's sorting algorithm is stable, so dictionaries with identical b values will retain their relative order).
from operator import itemgetter
tmp1 = sorted(mydictList, key=itemgetter('b'))
Next, use itertools.groupby to create subiterators that iterate over dictionaries with the same b value.
import itertools
tmp2 = itertools.groupby(tmp1, key=itemgetter('b))
Finally, create a new list that contains only the first element of each subiterator:
# Each x is a tuple (some-b-value, iterator-over-dicts-with-b-equal-some-b-value)
newdictList = [ next(x[1]) for x in tmp2 ]
Putting it all together:
from itertools import groupby
from operator import itemgetter
by_b = itemgetter('b')
newdictList = [ next(x[1]) for x in groupby(sorted(mydictList, key=by_b), key=by_b) ]
A very straight forward approach can go something like this:
mydictList= [{'a':1,'b':2,'c':3},{'a':2,'b':2,'c':4},{'a':2,'b':3,'c':4}]
b_set = set()
new_list = []
for d in mydictList:
if d['b'] not in b_set:
new_list.append(d)
b_set.add(d['b'])
Result:
>>> new_list
[{'a': 1, 'c': 3, 'b': 2}, {'a': 2, 'c': 4, 'b': 3}]
I'm going through a list of individual words and creating a dictionary where the word is the key, and the index of the word is the value.
dictionary = {}
for x in wordlist:
dictionary[x] = wordlist.index(x)
This works fine at the moment, but I want more indexes to be added for when the same word is found a second, or third time etc. So if the phrase was "I am going to go to town", I would be looking to create a dictionary like this:
{'I': 0, 'am' : 1, 'going' : 2, 'to': (3, 5), 'go' : 4, 'town' : 6}
So I suppose I need lists inside the dictionary? And then to append more indexes to them? Any advice on how to accomplish this would be great!
You can do this way:
dictionary = {}
for i, x in enumerate(wordlist):
dictionary.setdefault(x, []).append(i)
Explanation:
You do not need the call to index(). It is more efficient and cooler to use enumerate().
dict.setdefault() uses the first argument as key. If it is not found, inserts the second argument, else it ignores it. Then it returns the (possibly newly inserted) value.
list.append() appends the item to the list.
You will get something like this:
{'I': [0], 'am' : [1], 'going' : [2], 'to': [3, 5], 'go' : [4], 'town' : [6]}
With lists instead of tuples, and using lists even if it is only one element. I really think it is better this way.
UPDATE:
Inspired shamelessly by the comment by #millimoose to the OP (thanks!), this code is nicer and faster, because it does not build a lot of [] that are never inserted in the dictionary:
import collections
dictionary = collections.defaultdict(list)
for i, x in enumerate(wordlist):
dictionary[x].append(i)
>>> wl = ['I', 'am', 'going', 'to', 'go', 'to', 'town']
>>> {w: [i for i, x in enumerate(wl) if x == w] for w in wl}
{'town': [6], 'I': [0], 'am': [1], 'to': [3, 5], 'going': [2], 'go': [4]}
Objects are objects, regardless of where they are.
dictionary[x] = []
...
dictionary[x].append(y)
import collections
dictionary= collections.defaultdict(list)
for i, x in enumerate( wordlist ) :
dictionary[x].append( i )
A possible solution:
dictionary= {}
for i, x in enumerate(wordlist):
if not x in dictionary : dictionary[x]= []
dictionary[x].append( i )