I am trying to write a function which takes a list of strings containing names and
marks as a parameter. And return a dictionary of (mark, [list of names who got that mark])
Example:
def example(["John,5", "Jessica,5", "Jack,7"]):
Returns:
{'5' : ["John", "Jessica"], '7' : "Jack"}
I find this a tricky problem... How would I solve this using split(',')
This is what I've done so far:
def create_marks_dict(my_list):
dictionary = {}
for name in my_list:
if name not in dictionary:
dictionary[name]
return dictionary
You'll need to use defaultdict from collections to use lists in your dictionary
from collections import defaultdict
def create_marks_dict(my_list):
dictionary = defaultdict(list)
for item in my_list:
name, marks=item.split(',')
dictionary[marks].append(name)
return dictionary
output:
{'5' : ["John", "Jessica"], '7' : "Jack"}
If output of dict is required instead of defaultdict, you can cast dictionary while returning
return dict(dictionary)
You need to use collections.defaultdict:
from collections import defaultdict
marksdict = defaultdict(list)
for entry in ["John,5", "Jessica,5", "Jack,7"]:
name,mark = entry.split(',')
marksdict[mark].append(name)
print marksdict
this is the version that uses plain python dictionary:
def get_dict(nm_list):
d = {}
for n, m in [(name, mark) for (name, mark) in \
tuple([nm.split(',') for nm in nm_list])]:
d[m] = [n] if m not in d else d[m]+[n]
return d
la = ['John,5', 'Jessica,5', 'Jack,7']
d = get_dict(la)
print d
The output is: {'5': ['John', 'Jessica'], '7': ['Jack']}
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)
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've a list with master keys and a list of list of lists, where the first value of each enclosed list (like 'key_01') shall be a sub key for the corresponding values (like 'val_01', 'val_02'). The data is shown here:
master_keys = ["Master_01", "Master_02", "Master_03"]
data_long = [[['key_01','val_01','val_02'],['key_02','val_03','val_04'], ['key_03','val_05','val_06']],
[['key_04','val_07','val_08'], ['key_05','val_09','val_10'], ['key_06','val_11','val_12']],
[['key_07','val_13','val_14'], ['key_08','val_15','val_16'], ['key_09','val_17','val_18']]]
I would like these lists to be combined into a dictionary of dictionaries, like this:
master_dic = {
"Master_01": {'key_01':['val_01','val_02'],'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06']},
"Master_02": {'key_04': ['val_07','val_08'], 'key_05': ['val_09','val_10'], 'key_06': ['val_11','val_12']},
"Master_03": {'key_07': ['val_13','val_14'], ['key_08': ['val_15','val_16'], 'key_09': ['val_17','val_18']}
}
What I've got so far is the sub dict:
import itertools
master_dic = {}
servant_dic = {}
keys = []
values = []
for line in data_long:
for item in line:
keys.extend(item[:1])
values.append(item[1:])
servant_dic = dict(itertools.izip(keys, values))
Which puts out a dictionary, as expected.
servant_dic = {
'key_06': ['val_11','val_12'], 'key_04': ['val_08','val_07'], 'key_05': ['val_09','val_10'],
'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06'], 'key_01': ['val_01','val_02']
}
The problem is, that if I want to add the master_keys to this dictionary, so I get the wanted result, I'd have to do this in a certain order, which would be possible, if each line had a counter like this:
enumerated_dic =
{
0: {'key_01':['val_01','val_02'],'key_02': ['val_03','val_04'], 'key_03': ['val_05','val_06']},
1: {'key_04': ['val_07','val_08'], 'key_05': ['val_09','val_10'], 'key_06': ['val_11','val_12']},
2: {'key_07': ['val_13','val_14'], ['key_08': ['val_15','val_16'], 'key_09': ['val_17','val_18']}
}
I'd love to do this with enumerate(), while each line of the servant_dic is build, but can't figure out how. Since afterwards, i could simply replace the counters 0, 1, 2 etc. with the master_keys.
Thanks for your help.
master_keys = ["Master_01", "Master_02", "Master_03"]
data_long = [[['key_01','val_01','val_02'],['key_02','val_03','val_04'], ['key_03','val_05','val_06']],
[['key_04','val_07','val_08'], ['key_05','val_09','val_10'], ['key_06','val_11','val_12']],
[['key_07','val_13','val_14'], ['key_08','val_15','val_16'], ['key_09','val_17','val_18']]]
_dict = {}
for master_key, item in zip(master_keys, data_long):
_dict[master_key] = {x[0]: x[1:] for x in item}
print _dict
Hope this will help:
{master_key: {i[0]: i[1:] for i in subkeys} for master_key, subkeys in zip(master_keys, data_long)}
My functional approach:
master_dic = dict(zip(master_keys, [{k[0]: k[1::] for k in emb_list} for emb_list in data_long]))
print(master_dic)
You can also use pop and a dict comprehension:
for key, elements in zip(master_keys, data_long):
print {key: {el.pop(0): el for el in elements}}
...:
{'Master_01': {'key_02': ['val_03', 'val_04'], 'key_03': ['val_05', 'val_06']}}
{'Master_02': {'key_06': ['val_11', 'val_12'], 'key_04': ['val_07', 'val_08'], 'key_05': ['val_09', 'val_10']}}
{'Master_03': {'key_07': ['val_13', 'val_14'], 'key_08': ['val_15', 'val_16'], 'key_09': ['val_17', 'val_18']}}
This is my list:
volume = [['1.986', '3000'], ['1.987', '2000'], ['1.986', '700'],['1.987', '4000']]
How can I get the sum of volume[1] when volume[0] is the same price?
results = [['1.986', '3700'], ['1.987', '6000']]
Dictionaries would be a good data structure to use here. The default dict holds unique strings as the keys and assumes empty values are 0 because I set it to be based off of int.
from collections import defaultdict
d = defaultdict(int)
for v in volume:
d[v[0]] += int(v[1])
print d
If you need a list afterwards you can use a list comprehension:
list_version = [[key, value] for key,value in d]
I would like to create a dict where the value is a list of tuples
The code below produces a dict with lists of numbers, not list of tuples
mydict = {}
for line in file:
# read a
# read b
# read c
mydict[a] = (b, c) if a not in mydict else mydict[a].append((b, c))
Use defaultdict:
from collections import defaultdict
mydict = defaultdict(list)
for line in file:
a,b,c = line.split() # or something else
mydict[a].append((b,c))
You can also use setdefault when using normal dict's
mydict = {}
mydict.setdefault(a, list()).append((b,c))