如何使用列表推导式构建字典?

3

如何使用列表推导式构建字典?

我有两个列表。

 series = [1,2,3,4,5]
 categories = ['A', 'B', 'A', 'C','B']

我希望构建一个字典,其中类别是键。
谢谢你的回答,我想要产生:
 {'A' : [1, 3], 'B' : [2, 5], 'C' : [4]}

由于键不能重复存在。

你想要什么输出结果?{'A' : [1, 3], 'B' : [2, 5], 'C' : [4]} - Nobody moving away from SE
5个回答

11

你需要一个元组列表,元组是键值对。在这种情况下,你不需要使用推导式,只需使用zip:

dict(zip(categories, series))

生成 {'A': 3, 'B': 5, 'C': 4}(正如评论所指出的)。

编辑:注意,字典中不能有重复的键。因此,如果没有进一步澄清您想要什么解决方案,我不确定您正在寻找什么解决方案。

编辑:为了得到您想要的结果,最简单的方法可能是使用setdefault或defaultdict进行for循环。

categoriesMap = {}
for k, v in zip(categories, series):
    categoriesMap.setdefault(k, []).append(v)

这应该会产生 {'A': [1, 3], 'B': [2, 5], 'C': [3]}


这将产生“{'A': 3, 'C': 4, 'B': 5}”,我不确定这是否是OP想要的。 - DSM
谢谢Kris,尽管我的结果字典中只有3个项目。 - klabs
你应该使用defaultdict而不是标准的dictsetdefault。例如:map = defaultdict(list) - Voo
1
你正在覆盖 map(),请为你的字典使用不同的名称。 - Tadeck
@Voo 我知道。下面已经有人提供了默认字典解决方案,我想展示另一种方法。 - krousey

5
from collectons import defaultdict

series = [1,2,3,4,5]
categories = ['A', 'B', 'A', 'C','B']

result = defaultdict(list)
for key, val in zip(categories, series)
    result[key].append(value)

4

不必过于聪明(我有一个itertools的解决方案),使用传统的for循环也没有问题:

>>> from collections import defaultdict
>>> 
>>> series = [1,2,3,4,5]
>>> categories = ['A', 'B', 'A', 'C','B']
>>> 
>>> d = defaultdict(list)
>>> for c,s in zip(categories, series):
...     d[c].append(s)
... 
>>> d
defaultdict(<type 'list'>, {'A': [1, 3], 'C': [4], 'B': [2, 5]})

这段代码没有使用列表推导式,因为列表推导式并不适合这种情况。但是如果你非常想要一个列表推导式的话,可以尝试下面这种方式:

>> dict([(c0, [s for (c,s) in zip(categories, series) if c == c0]) for c0 in categories])
{'A': [1, 3], 'C': [4], 'B': [2, 5]}

这段代码不仅使用了一个,而是两个列表推导式,而且非常低效。


这是最佳答案,但不使用列表推导。 - klabs
{c0: [s for c, s in zip(categories, series) if c == c0] for i, c0 in enumerate(categories) if c0 not in categories[i+1:]},顺便说一下,内部循环仍然是列表推导式。 :\ - neizod

1
原则上,您可以像Kris建议的那样做:dict(zip(categories, series)),但请注意categories中不能有重复项(就像您的示例代码中一样)。 编辑: 现在您已经澄清了您的意图,这将按预期工作:
from collections import defaultdict
d = defaultdict(list)
for k, v in zip(categories, series):
    d[k].append(v)

0
d={ k:[] for k in categories }
map(lambda k,v: d[k].append(v), categories, series )

结果:

d is now = {'A': [1, 3], 'C': [4], 'B': [2, 5]}

或者(等同于)使用 setdefault(感谢 Kris R.)

d={}
map(lambda k,v: d.setdefault(k,[]).append(v), categories, series )

我想要的是 {'A' : [1, 3], 'B' : [2, 5], 'C' : [4]},而不是 {'A': 3, 'C': 4, 'B': 5}。 - klabs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接