I have the following list:
[('0-N', '3-C'), ('3-C', '5-C'), ('3-C', '9-C'), ('9-C', '12-C')]
I want to create the following dictionary with Key value pair from the list as:
{'0-N':['3-C'],'3-C':['0-N','5-C','9-C'],'9-C':['3-C','12-C'],'12-C':['9-C']}
Any suggestions or help will be highly appreciated.
Use collections.defaultdict:
from collections import defaultdict
lst = [('0-N', '3-C'), ('3-C', '5-C'), ('3-C', '9-C'), ('9-C', '12-C')]
dct = defaultdict(list)
for tup in lst:
dct[tup[0]].append(tup[1])
dct[tup[1]].append(tup[0])
dct = dict(dct)
print(dct)
{'0-N': ['3-C'], '3-C': ['0-N', '5-C', '9-C'], '5-C': ['3-C'], '9-C': ['3-C', '12-C'], '12-C': ['9-C']}
You may use built-in function dict.setdefault:
lst = [('0-N', '3-C'), ('3-C', '5-C'), ('3-C', '9-C'), ('9-C', '12-C')]
dct = {}
for a, b in lst:
dct.setdefault(a, []).append(b)
dct.setdefault(b, []).append(a)
Related
I've tried to word this the best way that I possibly can, but it will probably be more clear if I provide an example of what I am trying to acheive:
Input:
source_dictionary = {"person1": ["x1","x2","x3","x4"],
"person2": ["x1","x2","x3","x4"],
"person3": ["x1","x2"],
"person4": ["x1","x2"],
"person5": ["x1","x2"]
}
Intended output:
[["person1","person2"],["person3","person4","person5"]]
Handling the lists in the dictionary is proving to be quite a challenge.
Appologies, I forgot to include what I have tried so far. As mentioned above - I am having issues with the lists:
rev_dict = {}
for key, value in source_dictionary.items():
rev_dict.setdefault(value, set()).add(key)
result = [key for key, values in rev_dict.items()
if len(values) > 1]
Assuming you want to join the keys by identical value, use a defaultdict:
source_dictionary = {"person1": ["x1","x2","x3","x4"],
"person2": ["x1","x2","x3","x4"],
"person3": ["x1","x2"],
"person4": ["x1","x2"],
"person5": ["x1","x2"]
}
from collections import defaultdict
d = defaultdict(list)
for key, value in source_dictionary.items():
d[tuple(value)].append(key)
out = list(d.values())
Alternative with setdefault:
d = {}
for key, value in source_dictionary.items():
d.setdefault(tuple(value), []).append(key)
out = list(d.values())
output:
[['person1', 'person2'], ['person3', 'person4', 'person5']]
source_dictionary = {"person1": ["x1","x2","x3","x4"],
"person2": ["x1","x2","x3","x4"],
"person3": ["x1","x2"],
"person4": ["x1","x2"],
"person5": ["x1","x2"]
}
L = []
for i in source_dictionary.values():
K = []
for j in source_dictionary.keys():
if source_dictionary[j] == i :
K.append(j)
if K not in L:
L.append(K)
print(L)
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 am trying to come up with a neat way of doing this in python.
I have a list of pairs of alphabets and numbers that look like this :
[(a,1),(a,2),(a,3),(b,10),(b,100),(c,99),(d,-1),(d,-2)]
What I want to do is to create a new list for each alphabet and append all the numerical values to it.
So, output should look like:
alist = [1,2,3]
blist = [10,100]
clist = [99]
dlist = [-1,-2]
Is there a neat way of doing this in Python?
from collections import defaultdict
data = [('a',1),('a',2),('a',3),('b',10),('b',100),('c',99),('d',-1),('d',-2)]
if __name__ == '__main__':
result = defaultdict(list)
for alphabet, number in data:
result[alphabet].append(number)
or without collections module:
if __name__ == '__main__':
result = {}
for alphabet, number in data:
if alphabet not in result:
result[alphabet] = [number, ]
continue
result[alphabet].append(number)
But i think, that first solution more effective and clear.
If you want to avoid using a defaultdict but are comfortable using itertools, you can do it with a one-liner
from itertools import groupby
data = [('a',1),('a',2),('a',3),('b',10),('b',100),('c',99),('d',-1),('d',-2)]
grouped = dict((key, list(pair[1] for pair in values)) for (key, values) in groupby(data, lambda pair: pair[0]))
# gives {'b': [10, 100], 'a': [1, 2, 3], 'c': [99], 'd': [-1, -2]}
After seeing the responses in the thread and reading the implementation of defaultdict, I implemented my own version of it since I didn't want to use the collections library.
mydict = {}
for alphabet, value in data:
try:
mydict[alphabet].append(value)
except KeyError:
mydict[alphabet] = []
mydict[alphabet].append(value)
You can use defaultdict from the collections module for this:
from collections import defaultdict
l = [('a',1),('a',2),('a',3),('b',10),('b',100),('c',99),('d',-1),('d',-2)]
d = defaultdict(list)
for k,v in l:
d[k].append(v)
for k,v in d.items():
exec(k + "list=" + str(v))
I have the following Python list:
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EY:EE:KJERWEWERKJWE']
I would like to take the entries of this list and create a dictionary of key-values pairs that looks like
dictionary_list1 = {'EW':'G:B<<LADHFSSFAFFF', 'CB':'E:OWTOWTW', 'PP':'E:A,A<F<AF', 'GR':'A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX':'F:-111', 'DS':'f:115.5', 'MW':'AA:0', 'MA':'A:0XT:i:0', 'EW':'EE:KJERWEWERKJWE'}
How does one parse/split the list above list1 to do this? My first instinct was to try try1 = list1.split(":"), but then I think it is impossible to retrieve the "key" for this list, as there are multiple colons :
What is the most pythonic way to do this?
You can specify a maximum number of times to split with the second argument to split.
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EW:EE:KJERWEWERKJWE']
d = dict(item.split(':', 1) for item in list1)
Result:
>>> import pprint
>>> pprint.pprint(d)
{'CB': 'E:OWTOWTW',
'DS': 'f:115.5',
'EW': 'EE:KJERWEWERKJWE',
'GR': 'A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7',
'MA': 'A:0XT:i:0',
'MW': 'AA:0',
'PP': 'E:A,A<F<AF',
'SX': 'F:-111'}
If you'd like to keep track of values for non-unique keys, like 'EW:G:B<<LADHFSSFAFFF' and 'EW:EE:KJERWEWERKJWE', you could add keys to a collections.defaultdict:
import collections
d = collections.defaultdict(list)
for item in list1:
k,v = item.split(':', 1)
d[k].append(v)
Result:
>>> pprint.pprint(d)
{'CB': ['E:OWTOWTW'],
'DS': ['f:115.5'],
'EW': ['G:B<<LADHFSSFAFFF', 'EE:KJERWEWERKJWE'],
'GR': ['A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7'],
'MA': ['A:0XT:i:0'],
'MW': ['AA:0'],
'PP': ['E:A,A<F<AF'],
'SX': ['F:-111']}
You can also use str.partition
list1 = ['EW:G:B<<LADHFSSFAFFF', 'CB:E:OWTOWTW', 'PP:E:A,A<F<AF', 'GR:A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7', 'SX:F:-111', 'DS:f:115.5', 'MW:AA:0', 'MA:A:0XT:i:0', 'EW:EE:KJERWEWERKJWE']
d = dict([t for t in x.partition(':') if t!=':'] for x in list1)
# or more simply as TigerhawkT3 mentioned in the comment
d = dict(x.partition(':')[::2] for x in list1)
for k, v in d.items():
print('{}: {}'.format(k, v))
Output:
MW: AA:0
CB: E:OWTOWTW
GR: A:OUO-1-XXX-EGD:forthyFive:1:HMJeCXX:7
PP: E:A,A<F<AF
EW: EE:KJERWEWERKJWE
SX: F:-111
DS: f:115.5
MA: A:0XT:i:0
I have two lists:
list1 = [IM12345, IM12346, IM12347, IM12348]
list2 = [ID300, ID404, ID300, ID601]
list2 associates with the corresponding list1 values. list1 has unique values where as list2 has duplicates.
I want to make list2 unique corresponding associated value will add in the that list2 value.
Dict= {ID300: {IM12345, IM12347}, ID404: IM12346, ID601: IM12348}
Above pattern can be in list, set or dictionary.
Which algorithm in python should I use to get the above result?
You could try collections.defaultdict:
from collections import defaultdict
d = defaultdict(set)
list1 = ['IM12345', 'IM12346', 'IM12347', 'IM12348']
list2 = ['ID300', 'ID404', 'ID300', 'ID601']
for key, value in zip(list2, list1):
d[key].add(value)
Demo:
>>> d
defaultdict(<class 'set'>, {'ID300': {'IM12345', 'IM12347'}, 'ID404': {'IM12346'}, 'ID601': {'IM12348'}})
>>>
>>>
>>> for i, j in d.items():
... print(i, j)
...
...
ID601 {'IM12348'}
ID300 {'IM12345', 'IM12347'}
ID404 {'IM12346'}
You can create a dict to save the dataset
list1 = ["IM12345", "IM12346", "IM12347", "IM12348"]
list2 = ["ID300", "ID404", "ID300", "ID601"]
dictResult=dict()
i=0
for item in list2:
print item
if dictResult.has_key(item):
dictResult[item].append(list1[i])
else:
dictResult[item]=[list1[i]]
i=i+1
print dictResult
Result:
{'ID404': ['IM12346'], 'ID300': ['IM12345', 'IM12347'], 'ID601': ['IM12348']}
Might not completely be a pythonic way but - here it goes:
Map the input:
map = dict(zip(list1, list2))
Now you can do an inverse mapping:
inv_map = {}
for k, v in map.iteritems():
inv_map[v] = inv_map.get(v, [])
inv_map[v].append(k)
Result for the example above:
>>> inv_map
{'ID404': ['IM12346'], 'ID300': ['IM12345', 'IM12347'], 'ID601': ['IM12348']}
Another way of doing it could be with list operations.
yourList = ["1","2","3","4","1","2"]
newList = []
for f in yourList:
if f not in newList:
newList.append(f)
Simple solution
from collections import defaultdict
list1 = ['IM12345', 'IM12346', 'IM12347', 'IM12348']
list2 = ['ID300', 'ID404', 'ID300', 'ID601']
d = defaultdict(list)
for n in range(len(list2)):
d[list2[n]].append(list1[n])
print d.items()
Result:
[('ID404', ['IM12346']), ('ID300', ['IM12345', 'IM12347']), ('ID601', ['IM12348'])]
Python2.7 Documentation----defaultdict