Update dictionary and append if key exists - python

I've got a list of dictionarys.
list_of_dicts = [{ a: 1, b:f, c:3}, {a: y, b:q, c:z, d: 1}, ... ]
Now i want to create a new dictionary which looks like:
newDict = { a: [1,y], b: [f,q], c: [3,z], d:[1]}
I know i could could make a double for loop, but that is rather slow since I'm dealing with large objects (mostly NumPy arrays) in the dictionaries.
newDict = {}
for l in list_of_dicts:
for k, v in l.items():
if k in newDict:
newDict.append(v)
else:
newDict[k] = [v]
How to do this faster?

Using a collections.defaultdict() will improve the performance:
result = defaultdict(list)
for d in list_of_dicts:
for k, v in d.items():
result[k].append(v)

This is the fastest you can do this. You can replace the if with newdict.setdefault(k, []).append(v) to simplify it, but there is nothing you can do that will be faster than two loops.

Related

How to reverse dictionary items and list keys grouped by common values [duplicate]

This question already has answers here:
Dictionary comprehension for swapping keys/values in a dict with multiple equal values
(3 answers)
Closed 2 years ago.
I have a dictionary that I want to group by the common values:
init_dict = {'00001': 'string1', '00002': 'string2', '00003': 'string1', '00004': 'string3', '00005': 'string2'}
I want to create a new dictionary that groups the values and lists the keys like this:
new_dict = {'string1': ['00001', '00003'], 'string2':['00002', '00004'], 'string3': ['00004']}
I tried many things and this is the closest I can get.
lookup = 'string1'
all_keys = []
for k, v in init_dict.items():
if v == lookup:
all_keys.append(k)
print(all_keys)
This produces the first list: ['00001', '00003'] so I thought I could somehow loop through a list of lookup values but can't since I'm working with strings. Is there a way to do this and is there a way that is relatively efficient because my initial dictionary has 53,000 items in it. Any help would be much appreciated as I've been trying different things for hours.
Use a defaultdict, specifying a list as default argument, and append the corresponding values from the dictionary:
from collections import defaultdict
d = defaultdict(list)
for k,v in init_dict.items():
d[v].append(k)
print(d)
defaultdict(list,
{'string1': ['00001', '00003'],
'string2': ['00002', '00005'],
'string3': ['00004']})
You can use defaultdict
result = defaultdict(list)
for k, v in init_dict.items():
result[v].append(k)
or itertools.groupby
result = {k: [x[0] for x in v] for k, v in
groupby(sorted(init_dict.items(), key=lambda kv: kv[1]), key=lambda kv: kv[1])}
You can also use a normal dict (instead of defaultdict):
new_dict = {}
for key, val in init_dict.items():
if val in new_dict:
new_dict[val].append(key)
else:
new_dict[val] = []
new_dict[val].append(key)
Output:
new_dict = {'string1': ['00001', '00003'],
'string2': ['00002', '00005'],
'string3': ['00004']}

compare values from a list with values from a dictionary

I have a dictionary contains lists of values and a list:
dict={'first':45, 'second':30, 'third':56}
list= [30,45]
I want to compare the value in the dictionary with the list and a match to add to a new dictionary after that, remove from the old dict all the values that are in the new dict: I'm doing something like this:
def get_sessions(self, talks):
result_sessions = {}
for k, v in self.sessions.items():
for i in talks:
if v == i:
result_sessions[k] = v
for k, v in result_sessions.items():
del self.sessions[k]
return result_sessions
Maybe you know a more elegant solution? any help?
This is one approach.
Ex:
d ={'first':45, 'second':30, 'third':56}
lst = [30,45]
result_sessions = {k: v for k, v in d.items() if v in lst}
d = { k : d[k] for k in set(d) - set(result_sessions) }
print(result_sessions)
print(d)
Output:
{'second': 30, 'first': 45}
{'third': 56}

How to increment values for each key in dict?

In Python, how to iterate a dict and increment values of each key?
D = {k1:1, k2:2}
I want D to be {k1:2, k2:3}.
You can use a dict comprehension to increment each value, then assign it back
>>> {k: v+1 for k,v in D.items()}
{'k1': 2, 'k2': 3}
You can either modify (also called "mutate") the dictionary D:
for k in D.keys():
D[k] = D[k] + 1
Or you can create a new dictionary and re-assign D to it:
D = { k: v+1 for k, v in D.items() }
The difference will become apparent if something else points at D, or if D is very large and takes longer to re-create than to update in-place.
D = {"k1":1, "k2":2}
for i in D:
D[i] += 1
print(D)
Seems to do the trick, I wasnt sure on the k1 / k2 so i made them strings for testing
I have another solution for you, I hope it is useful.
for key in D:
D[key] +=1

update one dictionary with another by adding values rather then replacing it

I have many dictionaries like this:
dict1 = {1:[1,2,3],2:[2,3,4]}
dict2 = {2:[3,4,5],3:[4,5,6]}
I need to get
dict = {1:[1,2,3],2:[2,3,4,3,4,5],3:[4,5,6]}
# ^
# | order is unimportant
What is the best way of doing it?
Simple iteration an extending list...
for key, value in dict2.iteritems():
dict1.setdefault(key, []).extend(value)
Iterate through the keys of dict2; if the same key exists in dict1, concatenate the lists and set in dict1; otherwise just set in dict1
dict1 = {1:[1,2,3],2:[2,3,4]}
dict2 = {2:[3,4,5],3:[4,5,6]}
dicts = [dict1, dict2]
new_dict = {}
for d in dicts:
for k, v in d.iteritems():
if new_dict.has_key(k):
new_dict[k] = new_dict[k] + v
else:
new_dict[k] = v
a = {'a' : [1,2], 'b' : [3,4]}
b = {'a' : [3,4], 'b' : [1,2]}
for key in a.keys():
for elem in a[key]:
b[key].append(elem)
Oh, maybe there's some clever way to do it with reduce, but why not just write code like a normal person.
dict = {}
for each_dict in (dict1, dict2, ...): # ... is not real code
for key, value in each_dict:
if not dict.has_key(key):
dict[key] = []
dict[key] += value # list append operator
I have many dictionaries like this:
This way lets you "glue together" multiple dictionaries at a time:
dict(
(k, sum((d.get(k, []) for d in dicts), []))
for k in set(sum((d.keys() for d in dicts), []))
)

Python: How to construct a tuple, value dictionary from a list of key,value dictionary?

I have a list of dicts as follows:
lst = [{'unitname':'unit1', 'test1': 2, 'test2': 9}, {'unitname':'unit2', 'test1': 24, 'test2': 35}]
How do I contruct a single dict as follows:
dictA = { ('unit1','test1'): 2, ('unit1','test2'): 9, ('unit2','test1'):24, ('unit2','test2' : 35 }
`
I have all the unit names & test names in a list:
unitnames = ['unit1','unit2']
testnames = ['test1','test2']
I tried but missed out some tests for some units.
dictA = {}
for unit in unitnames:
for dict in lst:
for k,v in dict.items():
dictA[unit,k] = v
Advices? Thanks.
dict(((d['unitname'], k), t)
for d in lst
for (k, t) in d.iteritems()
if k != 'unitname')
You could try:
dictA = {}
for l in lst:
name = l.pop('unitname')
for test in l:
dictA[name, test] = l[test]
Posted at the same time and with the same assumptions as Gareth's solution - however this will not give you the extra item of (name, 'unitname') = name
Marcelo Cantos's solution is quite elegant, but would be easier for mere mortals like us to parse like this:
dict( ((d['unitname'], k), t)
for d in lst
for (k, t) in d.iteritems()
if k != 'unitname'
)
dictA = {}
for d in lst:
unit = d['unitname']
for test in testnames:
if test in d:
dictA[unit,test] = d[test]
I'm assuming (1) that all the dicts in your list have a unitname key, (2) that its value is always one of the units you're interested in, (3) that some dicts in the list may have entries for tests you aren't interested in, and (4) that some tests you're interested in may be absent from some dicts in the list. Those assumptions are a bit arbitrary; if any happen to be wrong it shouldn't be hard to adjust the code for them.

Categories

Resources