是否有更紧凑的方法将一系列 (key,value) 元组转换为 {key:[value,..],..} 字典?

Is there a more compact way to convert a sequence of (key,value) tuples into a {key:[value,..],..} dict?

我有一个元组序列 itemList,格式为 (key, value),我想将该列表中的项目转换为 dict,格式为 {key : [value, ..], ..}。一个特定的 key 值可能会多次出现在 itemList 中,并带有匹配的或新的 value,我也想记录这些值(这就是为什么简单地使用 dict(itemList)不工作)。

我正在使用 Python2.7.9 并寻找将此代码小型化的方法:

newDict = dict()
for k,v in itemList:  # itemList contains the tuples described above.
    if k in newDict:
        newDict[k].append(v)
    else:
        newDict[k] = [v]

我试过将 map()list-comprehensionsnewDict.update(..) 结合使用,但 none 的效果符合预期。

我查看了 this similar question,,但我输入的格式和期望的输出有很大不同。

(对于那些想知道的人,"Why would you want to change this perfectly acceptable code?":我有兴趣寻找更多应用 Python 的内置函数和模块的替代方法一种学术练习,而不是有目的地避免一些功能性和可理解的东西。)

这一行可以替换发布的代码,但更难阅读。它可能也不是很快,因为它必须迭代 itemList 几次。

newDict = dict((k, [_v for _k,_v in itemList if _k == k]) for k in set(i[0] for i in itemList))

您可以使用 dict.setdefault 来缩短您的代码,像这样

newDict = {}
for k, v in itemList:
    newDict.setdefault(k, []).append(v)

setdefault会在字典中查找键,如果没有找到它会分配第二个参数给它,return它。

如果在字典中找到键,它会简单地return对应的值。


或者,您可以使用 collections.defaultdict,像这样

from collections import defaultdict

result = defaultdict(list)
for k, v in itemList:
    result[k].append(v)

这类似于 setdefault 方法。如果在字典中找不到该键,则将调用传递给 defaultdict 构造函数的函数来创建一个新值。