在Python中合并列表字典

26 投票
6 回答
31786 浏览
提问于 2025-04-15 14:41

我有一大堆(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

因为这个方法只在键重叠的情况下使用列表连接,所以如果重叠的键不多,它会更快。

撰写回答