我有一个字典,其中每个值都是一个列表,如下所示:
dictA = {1:['a','b','c'],2:['d','e']}
不幸的是,我无法改变这种结构来解决我的问题
我想将列表的所有条目收集到一个列表中,如下所示:
['a','b','c','d','e']
此外,我想在if-block中只执行一次。由于我只想做一次,我不想将它存储到一个中间变量,所以自然地,列表理解是要走的路。但是怎么样?我的第一个猜测,
[dictA[key] for key in dictA.keys()]
产量,
[['a','b','c'],['d','e']]
因为
而无效'a' in [['a','b','c'],['d','e']]
收益False
。我尝试的其他所有内容都使用了某种非法语法。
我如何表现这种理解?
答案 0 :(得分:7)
循环返回列表 (直接在字典上循环也为你提供键):
[value for key in dictA for value in dictA[key]]
或更直接使用dictA.itervalues()
:
[value for lst in dictA.itervalues() for value in lst]
列表推导让你嵌套循环;阅读上面的循环,好像它们以相同的顺序嵌套:
for lst in dictA.itervalues():
for value in lst:
# append value to the output list
或使用itertools.chain.from_iterable()
:
from itertools import chain
list(chain.from_iterable(dictA.itervalues()))
后者采用一系列序列,让你循环遍历它们,好像它们是一个大的列表。 dictA.itervalues()
为您提供了一系列列表,chain()
将它们放在一起,以便list()
迭代并构建一个大列表。
如果您正在测试所有值中的成员身份,那么您真正想要的是一种简单的方法来遍历所有值,并针对每个值测试您的值,直到找到一场比赛。 any()
function以及合适的生成器表达式就是这样:
any('a' in lst for lst in dictA.itervalues())
一旦True
中的任何值列出dictA
,就会返回'a'
,并提前停止.itervalues()
循环。
答案 1 :(得分:2)
如果您确实要检查会员资格(您的a in...
示例),则可以将其重写为:
if any('a' in val for val in dictA.itervalues()):
# do something
如果实际上不需要,则可以节省必须压扁列表。
答案 2 :(得分:0)
在这种特殊情况下,您可以使用嵌套理解:
[value for key in dictA.keys() for value in dictA[key]]
但总的来说,如果您已经想出如何将某些内容转换为嵌套列表,则可以使用chain.from_iterable
展平任何嵌套的可迭代:
itertools.chain.from_iterable(dictA[key] for key in dictA.keys())
这将返回一个迭代器,而不是一个列表;如果您需要一个列表,请明确地执行:
list(itertools.chain.from_iterable(dictA[key] for key in dictA.keys()))
作为旁注,for key in dictA.keys()
与for key in dictA
做同样的事情,除了在旧版本的Python中,它会浪费时间和内存来制作额外的密钥列表。正如the documentation所述,iter
上的dict
与iterkeys
相同。
因此,在上述所有版本中,最好只使用in dictA
。
答案 3 :(得分:0)
在简单的代码中,只是为了理解这可能会有所帮助
ListA=[]
dictA = {1:['a','b','c'],2:['d','e']}
for keys in dictA:
for values in dictA[keys]:
ListA.append(values)
答案 4 :(得分:-1)
你可以做一些......
output_list = []
[ output_list.extend(x) for x in {1:['a','b','c'],2:['d','e']}.values()]
output_list将是['a','b','c','d','e']