在Python中合并列表字典
我有一大堆(p, q)的组合,想把它们转换成一个字典,字典里的每个键对应一个列表,这个列表里放的是q的值。
举个例子:
Original List: (1, 2), (1, 3), (2, 3)
Resultant Dictionary: {1:[2, 3], 2:[3]}
另外,我还想高效地把这些字典合并在一起。
再举个例子:
Original Dictionaries: {1:[2, 3], 2:[3]}, {1:[4], 3:[1]}
Resultant Dictionary: {1:[2, 3, 4], 2:[3], 3:[1]}
这些操作是在一个内部循环里进行的,所以我希望它们能尽可能快。
提前谢谢你!
6 个回答
3
这是一个一行代码的解决方案:
>>> a = {1:[2, 3], 2:[3]}
>>> b = {1:[4], 3:[1]}
>>>
>>> result = {key: a.get(key, []) + b.get(key, []) for key in (a.keys() | b.keys())}
>>> result
{1: [2, 3, 4], 2: [3], 3: [1]}
12
collections.defaultdict
的工作原理是这样的:
from collections import defaultdict
dic = defaultdict(list)
for i, j in tuples:
dic[i].append(j)
对于字典(dict)也是类似的:
a, b = {1:[2, 3], 2:[3]}, {1:[4], 3:[1]}
de = defaultdict(list, a)
for i, j in b.items():
de[i].extend(j)
19
如果这个元组列表是排好序的,@gnibbler 提到的 itertools.groupby
其实是个不错的选择,跟 defaultdict
比起来,它的用法有点不同:
import itertools
import operator
def lot_to_dict(lot):
key = operator.itemgetter(0)
# if lot's not sorted, you also need...:
# lot = sorted(lot, key=key)
# NOT in-place lot.sort to avoid changing it!
grob = itertools.groupby(lot, key)
return dict((k, [v[1] for v in itr]) for k, itr in grob)
关于如何把多个字典的列表合并成一个新的字典列表……:
def merge_dols(dol1, dol2):
keys = set(dol1).union(dol2)
no = []
return dict((k, dol1.get(k, no) + dol2.get(k, no)) for k in keys)
我给 []
起了个别名叫 no
,这样可以避免不必要地创建很多空列表,因为性能是很重要的。如果这些字典的键有一些重叠,使用下面的方法会更快:
def merge_dols(dol1, dol2):
result = dict(dol1, **dol2)
result.update((k, dol1[k] + dol2[k])
for k in set(dol1).intersection(dol2))
return result
因为这个方法只在键重叠的情况下使用列表连接,所以如果重叠的键不多,它会更快。