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), []))
)
Related
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']}
I currently have two dictionaries containing nucleotide strings as the key and their counts as the value.
example:
dict1 = {GGA:64231, GAT: 66582}
dict2 = {TCC:64231, ATC: 66582}
I want to make a new dictionary that looks like this:
dict3 = {'GGA:TCC':64231, 'GAT:ATC':66582}
How can I do this?
Simply swap the key/value pairs in the dictionary to build your new one (assuming you have unique values, and your dictionaries all have matching values):
Python 3:
dict1 = {'GGA':64231, 'GAT': 66582}
dict1 = {v:k for k,v in dict1.items()} # {66582: 'GAT', 64231: 'GGA'}
dict2 = {'TCC':64231, 'ATC': 66582}
dict2 = {v:k for k,v in dict2.items()} # {66582: 'ATC', 64231: 'TCC'}
dict3 = {"{}:{}".format(dict1[k],dict2[k]):k for k in dict1} # {'GGA:TCC': 64231, 'GAT:ATC': 66582}
Python 2.7 use iteritems() instead of items()
The way I would do that is using list comprehension, which I believe is more pythonic:
dict1 = {GGA:64231, GAT: 66582}
dict2 = {TCC:64231, ATC: 66582}
new_dict = { x+":"+y:dict1[x] for x in dict1.keys() for y in dict2.keys() if dict1[x] == dict2[y]}
And this is the output:
{'GGA:TCC': 64231, 'GAT:ATC': 66582}
i think it would be smarter to map them with the key as the numbers for example since they are the defining factor.
a={i:[w] for w,i in dict1.items()}
b={i:w if i not in a else a[i]+[w] for w,i in dict2.items()}
output
{64231: ['GGA', 'TCC'], 66582: ['GAT', 'ATC']}
or in your case
a={i:[w] for w,i in dict1.items()}
b={i:w if i not in a else ":".join(a[i]+[w]) for w,i in dict2.items()}
output
{64231: 'GGA:TCC', 66582: 'GAT:ATC'}
What a fun little problem. My version doesn't search the dict, it assumes your dicts have perfect information and the values can be sorted by the number value.
dict1 = {"GGA": 64231, "GAT": 66582}
dict2 = {"TCC": 64231, "ATC": 66582}
dict3 = {
"%s:%s" % (k, l): v
for (k, v), (l, b) in zip(
sorted(dict1.items(), key=lambda x: x[1]),
sorted(dict2.items(), key=lambda x: x[1]),
)
}
print(dict3)
I'll say though #TheoretiCAL's answer is likely the best.
One way may be to try using defaultdict:
from collections import defaultdict
dict1 = {'GGA':64231, 'GAT': 66582}
dict2 = {'TCC':64231, 'ATC': 66582}
result_dict = defaultdict(list)
# read first dictionary and add value as key and key to list of values
for k, v in dict1.items(): result_dict[v].append(k)
# read other dictionary and add value as key and key to list of values
for k, v in dict2.items(): result_dict[v].append(k)
# change key to value in dicitonary
result_dict = {':'.join(v):k for k, v in result_dict.items()}
print(result_dict)
Output:
{'GAT:ATC': 66582, 'GGA:TCC': 64231}
I have a dictionary:
d = {1:[9,9,9],2:[8,8,8],3:[7,7,7]}
and a list of keys :
newkeylist = [4,2,3]
Now i want check the keys in the dict with the content in the list. If they are different i want to replace the key in the dict with the one in the list.
for i in range(len(newkeylist)):
if d.key()[i] != newkeylist[i]:
d.key()[i] = newkeylist[i]
try something like this
d = {1:[9,9,9],2:[8,8,8],3:[7,7,7]}
newkeylist = [4,2,3]
d_copy = d.copy()
for i, (k, v) in enumerate(d_copy.items()):
if k != newkeylist[i]:
d[newkeylist[i]] = v
del d[k]
but as #jonrsharpe said, it's not an ordered dict: the output is random
I have two dictionaries, the first is a dictionary of dictionaries.
dict = {k1:{kk1:vv1, kk2: vv2}, k2:{kkk1:vvv1, kkk2:vvv2}}
dict1 = dict['k2']
# So basically:
# dict1 = {kkk1:vvv1, kkk2:vvv2}
dict3 = {vvv1:actualv1, vvv2:actualv2}
I want the end result to be:
dict1 = {kkk1:actualv1, kkk2:actualv2}
Which is basically:
dict = {k1:{kk1:vv1, kk2: vv2}, k2:{kkk1:actualv1, kkk2:actualv2}}
So, I have tried dictionary comprehension:
{k: dict2.get(v, v) for k, v in dict1.items()}
But to no avail. I have tried to be as clear as possible. One more thing I'd like to mention is that The 'dict' contains about 400 k-v pairs. I have given an example of what I would like to achieve. Help.
Patching the dict1 alone and inplace, accordint to dict3, can be done like this:
d = dict(k1=dict(kk1='vv1', kk2='vv2'),
k2=dict(kkk1='vvv1', kkk2='vvv2'))
dict1 = d['k2']
dict3 = dict(vvv1='actualv1', vvv2='actualv2')
for k in dict1:
v = dict1[k]
try:
dict1[k] = dict3[v]
except KeyError:
pass
print d
prints:
{'k2': {'kkk2': 'actualv2', 'kkk1': 'actualv1'},
'k1': {'kk1': 'vv1', 'kk2': 'vv2'}}
You can try this:
dict = {'k1':{'kk1':'vv1', 'kk2': 'vv2'}, 'k2':{'kkk1':'vvv1', 'kkk2':'vvv2'}}
dict3 = {'vvv1':'actualv1', 'vvv2':'actualv2'}
final_data = {a:{c:dict3.get(d, d) for c, d in b.items()} for a, b in dict.items()}
Output:
{'k1': {'kk1': 'vv1', 'kk2': 'vv2'}, 'k2': {'kkk1': 'actualv1', 'kkk2': 'actualv2'}}
Ok, so you want to process a sub dict from a dict of dicts, given its key, and replace values according to a replacement dict original_value => replacement_value.
You can just do it:
def patch_dic(dic, key, dict3):
for k,v in dic[key].items(): # iterate the sub dict
for orig, repl in dict3.items(): # iterate the replacement dict
if v == orig: # if a value exists in the replacement dict
dic[key][k] = repl # just replace it
Demo:
>>> dic = {'k1':{'kk1':'vv1', 'kk2': 'vv2'}, 'k2':{'kkk1':'vvv1', 'kkk2':'vvv2'}}
>>> patch_dic(dic, 'k2', {'vvv1':'actualv1', 'vvv2':'actualv2'})
>>> print(dic)
{'k1': {'kk1': 'vv1', 'kk2': 'vv2'}, 'k2': {'kkk1': 'actualv1', 'kkk2': 'actualv2'}}
I have two dictionaries. In both dictionaries, the value of each key is a single list. If any element in any list in dictionary 2 is equal to a key of dictionary 1, I want to replace that element with the first element in that dictionary 1 list.
In other words, I have:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb']}
and I want:
dict2 = {1:['newA', 'newB']}
I tried:
for ID1, news in dict1.items():
for x, ID2s in dict2.items():
for ID in ID2s:
if ID == ID1:
print ID1, 'match'
ID.replace(ID, news[0])
for k, v in dict2.items():
print k, v
and I got:
IDb match
IDa match
1 ['IDa', IDb']
So it looks like everything up to the replace method is working. Is there a way to make this work? To replace an entire string in a value-list with a string in another value-list?
Thanks a lot for your help.
Try this:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb']}
for key in dict2.keys():
dict2[key] = [dict1[x][0] if x in dict1.keys() else x for x in dict2[key]]
print dict2
this will print:
{1: ['newA', 'newB']}
as required.
Explanation
dict.keys() gives us just the keys of a dictionary (i.e. just the left hand side of the colon). When we use for key in dict2.keys(), at present our only key is 1. If the dictionary was larger, it'd loop through all keys.
The following line uses a list comprehension - we know that dict2[key] gives us a list (the right side of the colon), so we loop through every element of the list (for x in dict2[key]) and return the first entry of the corresponding list in dict1 only if we can find the element in the keys of dict1 (dict1[x][0] if x in dict1.keys) and otherwise leave the element untouched ([else x]).
For example, if we changed our dictionaries to be the following:
dict1 = {'IDa':['newA', 'x'], 'IDb':['newB', 'x']}
dict2 = {1:['IDa', 'IDb'], 2:{'IDb', 'IDc'}}
we'd get the output:
{1: ['newA', 'newB'], 2: ['newB', 'IDc']}
because 'IDc' doesn't exist in the keys of dict1.
You could also use dictionary comprehensions, but I am not sure that they are working in Python 2.7, it may be limited to Python 3 :
# Python 3
dict2 = {k: [dict1.get(e, [e])[0] for e in v] for k,v in dict2.items()}
edit: I just checked, this is working in Python 2.7. However, dict2.items() should be replaced by dict2.iteritems() :
# Python 2.7
dict2 = {k: [dict1.get(e, [e])[0] for e in v] for k,v in dict2.iteritems()}
This was a fun one!
dict2[1] = [dict1[val][0] if val in dict1 else val for val in dict2[1]]
Or, here is the same logic without list comprehension:
new_dict = {1: []}
for val in dict2[1]:
if val in dict1:
new_dict[1].append(dict1[val][0])
else:
new_dict[1].append(val)
dict2 = new_dict