I have a list of lists:
[['a', 1],['b', 2]['c', 3]['c', 1]['c', 9]['d', 8]['d', 4]]
I want to make a dictionary with :
{ a:1, b:2, c:[3,1,9],d:[8,9]}
I have tried the following:
count = 0
sw_fd_dict = {}
value_list =[]
sw_fd_list2 = [['a', 1],['b', 2],['c', 3],['c', 1],['c', 9],['d', 8],['d', 4]]
while count < len(sw_fd_list2):
try:
# to check for repeated keys like "c"
if sw_fd_list2[count][0] != sw_fd_list2[count-1][0]:
sw_fd_dict[sw_fd_list2[count][0]] = sw_fd_list2[count][1]
elif sw_fd_list2[count][0] == sw_fd_list2[count-1][0]:
value_list.append(sw_fd_list2[count-1][1])
value_list.append(sw_fd_list2[count][1])
sw_fd_list2[count][1] =value_list
sw_fd_dict[sw_fd_list2[count][0]] = sw_fd_list2[count][1]
except Exception as e:
print str(e)
count += 1
print sw_fd_dict
Is there a better way to do this?
This is a shorter approach:
result = {}
for (key, value) in the_list:
result.setdefault(key, []).append(value)
setdefault
returns the value (like get
) but sets it first if it's not present. ( defaultdict
also works fine here.)
On rereading the question, if you really want the single numbers to not be lists, you can put in some more conditions. I edited this to use a set
rather than checking whether the existing value was appendable, in order to be 'safe' in case your values are collections rather than numbers.
result = {}
seen = set()
for (key, value) in the_list:
if key not in result:
result[key] = value
elif key not in seen:
result[key] = [result[key], value]
seen.add(key)
else:
result[key].append(value)
Or, a nice way of converting the defaultdict-style answer to the one with individual numbers not in lists:
result = {
key: value[0] if len(value) == 1 else value
for key, value in result.items()}
You can use defaultdict
in the collections
package:
from collections import defaultdict
sw_fd_dict = defaultdict(list)
sw_fd_list2 = [['a', 1],['b', 2], ['c', 3], ['c', 1], ['c', 9], ['d', 8], ['d', 4]]
for key, val in sw_fd_list2:
sw_fd_dict[key].append(val)
sw_fd_dict
Out[8]: defaultdict(<type 'list'>, {'a': [1], 'c': [3, 1, 9], 'b': [2], 'd': [8, 4]})
Then you convert it to a traditional dict
:
dict(sw_fd_dict)
Out[9]: {'a': [1], 'b': [2], 'c': [3, 1, 9], 'd': [8, 4]}
EDIT: Quentin THEURET pointed out that I didn't replicate the exact results you want. Thanks to his comment, I've noticed that you require the single value to be an integer on its own, instead wrapped in a list. You can then perform some post-processing:
d = dict(sw_fd_dict)
for k in d.keys():
if len(d[k]) == 1:
d[k] = d[k][0]
d
Out[15]: {'a': 1, 'b': 2, 'c': [3, 1, 9], 'd': [8, 4]}
def list_to_dict(l):
d = {}
for key, val in l:
if key in d:
if isinstance(d[key], list):
d[key].append(val)
else:
d[key] = [d[key], val]
else:
d[key] = val
return d
sw_fd_list2 = [['a', 1],['b', 2],['c', 3],['c', 1],['c', 9],['d', 8],['d', 4]]
res = list_to_dict(sw_fd_list2)
Pretty similar question: https://stackoverflow.com/a/960753/1317856
>>> l = [['a', 1],['b', 2]['c', 3]['c', 1]['c', 9]['d', 8]['d', 4]]
>>> from collections import defaultdict
>>> d = defaultdict(list)
>>> for a, b in l:
d[a].append(b)
>>> dict(d)
{'a': [1], 'c': [3, 1, 9], 'b': [2], 'd': [8, 4]}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.