Python一行代码将字典中的列表值保存到列表中

5
我希望能够用一行代码编写for循环:
d = {'a': [1, 2, 3], 'b': [5, 6, 7], 'c': [9, 0]}

my_list = []
for k, v in d.items():
    for x in v:
        my_list.append(x)

我该如何做呢?


不是与问题相关,但请注意,“list”和“dict”都是非常糟糕的变量名称,因为它们分别是“[]”和“{}”的内置构造函数。 - Yuushi
@Yuushi 哎呀,是的,我本来也想提到的,但忘了。我会编辑它们。 - jamylak
4个回答

9
>>> d = {'a': [1, 2, 3], 'b': [5, 6, 7], 'c': [9, 0]}
>>> [y for x in d.values() for y in x]
[1, 2, 3, 9, 0, 5, 6, 7]

这是一个嵌套的列表推导式。为了展示其工作原理,你可以将它拆分成若干行以便看到它作为嵌套for循环的结构。它从左到右执行。

[y 
 for x in d.values() 
 for y in x]

我该如何理解这样使用双重循环的代码呢?我不知道变量分别代表什么 xD - bandit
@bandit 我编辑了答案以展示它的工作原理。如果你不知道,这是一个列表推导式。 - jamylak
1
@jamylak 我知道这是列表推导式,我只是认为我应该使用类似于 [x for x in v for v in d.values()] 的东西。现在我明白如何编写它了。谢谢。 - bandit

1
list(itertools.chain(*d.values()))

正如@jamylak所建议的那样,以下代码可以更加高效,因为它避免了*操作符进行完整解包的过程:
list(itertools.chain.from_iterable(d.values()))

在Python 2.x中,使用.itervalues代替.values,以避免不必要的列表复制。

1
你的意思是 chain.from_iterable - jamylak
@jamylak,是的,我的回答没有完全起作用。我通过添加 * 来修复它。 - shx2
这几乎是等价的,只不过您必须先解包所有值,chain.from_iterable 应该更有效率。 - jamylak
@jamylak,谢谢。我把你的建议加到了问题中(尽管原始发布者没有提到速度是优先考虑因素)。 - shx2
1
好的,你有我的赞成。对于大型列表而言,这可能是最快的方法,因为它将所有内容保持在C级别,只调用由C实现的函数,使其更快,避免了Python的开销。但是,在大多数实际情况下,我认为我的方法会更快。 - jamylak
你可以添加一条信息,即在Python3中方法itervalues已被移除,在这种情况下应使用iter(d.values()) - halex

1
如何?
ll = []
for l in d.values(): 
    ll.extend(u)

0
使用运算符重载 -
sum(d.values(), [])

注意:这个程序的运行时间为O(N^2)。而且在Py3k中不能直接使用。 - jamylak

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