如何从列表列表中创建字典

3
这是我正在做的事情:
当数据是一个列表嵌套列表时,形式为[[int1, int2, int3], [int1, int2, int3]]
我想要一个字典,看起来像这样:{int1: [int2, int3], in2:[int2, int3]}。我在执行字典推导之前检查数据的大小,它是1417。
然后我检查字典的长度,它大约为11,我不知道正在发生什么,因为并没有将所有元素复制到containsBacon中。
def makeComprehension(data):
    containsBacon = dict([(movies[2], movies[0:2]) for movies in data])

每个子列表包含3个元素,对吧?那么你想把哪个元素作为字典键,第一个还是最后一个?你的描述表明是第一个,但你的代码使用了movies[2],这是最后一个。哪个是正确的? - Tom Karzes
1
containsBacon = dict([(movies[0], movies[1:]) for movies in data]) 这段代码可以运行。 - Ananth
创建containsBacon之后,您是否打算返回它?还是您希望它作为全局变量可用?如果您希望返回它,则需要在结尾添加return containsBacon。如果您希望它在全局中可用,则需要在函数顶部添加global containsBacon。否则,该函数将不起任何作用。 - Tom Karzes
1
你可能有重复的键导致了你的列表长度和字典长度之间的差异。 - dazedconfused
2个回答

0
这是一种实现的方法:
>>> l = [[1,2,3], [10,20,30]]
>>> d = {m[0]:m[1:] for m in l}
>>> d
{1: [2, 3], 10: [20, 30]}

请注意,并非所有元素都会出现在结果字典中,因为如果两个列表以相同的元素开头,则会创建相同的键,因此不会出现。
如果您想在结果字典中包含所有原始元素,可以执行以下操作:
>>> l = [[1,2,3], [10,20,30], [1,5,6]
>>> {m[0]:[x for n in l if n[0]==m[0] for x in n[1:]] for m in l}
{1: [2, 3, 5, 6], 10: [20, 30]}

0

与@DevShark的答案类似,但使用解构赋值:

>>> L = [[1,2,3], [10,20,30], [1,5,6]]
>>> {k:v for k,*v in L}
{1: [5, 6], 10: [20, 30]}

如果您想将给定键的值连接起来,请不要使用字典推导式:
>>> d = {}
>>> for k,*v in L: d.setdefault(k, []).extend(v)
...
>>> d
{1: [2, 3, 5, 6], 10: [20, 30]}

setdefault 方法会创建一个 d[k] 条目,如果它不存在,则将其设置为空列表。这个解决方案的时间复杂度为 O(n),相对于 @DevShark 回答中的 O(n^2)。

下面是另一个 O(n) 版本:

>>> import functools
>>> functools.reduce(lambda d,m:{**d, m[0]:d.get(m[0], []) + m[1:]}, L, {})
{1: [2, 3, 5, 6], 10: [20, 30]}

d[m[0]]被更新为其上一个值+m[1:]

如果你想要一个字典推导,你可以使用itertools.groupby来得到一个O(n lg n)的解决方案:

>>> import itertools
>>> L.sort() # O(n lg n) part
>>> L
[[1, 2, 3], [1, 5, 6], [10, 20, 30]]
{k:[v for m in ms for v in m[1:]] for k, ms in itertools.groupby(L, lambda m:m[0])}
{1: [2, 3, 5, 6], 10: [20, 30]}

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