我有这样的事情:
class C:
def get_data(): returns a list
d = {several instances of C}
现在,我如何迭代所有列表的所有元素?我悲惨地失败了:
[e for e in [v.get_data() for _, v in d.items()]]
内部循环将生成一个列表,这些列表无法被外部循环消化。
答案 0 :(得分:4)
你想要扁平化:
[e for _, v in d.items() for e in v.get_data()]
注意循环的顺序。
答案 1 :(得分:3)
import itertools
class C:
def get_data(self): return ['a','b']
d = {'a' : C(), 'b' : C()}
print [e for e in itertools.chain.from_iterable(v.get_data() for v in d.values())]
将打印
['a', 'b', 'a', 'b']
答案 2 :(得分:2)
只需修改现有的表达式 -
[item for sublist in [v.get_data() for _, v in d.items()] for item in sublist]
答案 3 :(得分:1)
@ piokuc的答案是更好的选择,但在Python 3中,yield from
是可能的:
class C:
def get_data(self):
return ['a','b']
def extract(dict_):
"""Yield elements from sublists."""
for _, v in dict_.items():
yield from v.get_data()
d = {'a' : C(), 'b' : C()}
[e for e in extract(d)]
# ['a', 'b', 'a', 'b']
答案 4 :(得分:0)
不确定你的意思"迭代所有元素",但根据你问题中的代码,以下内容将创建Python 2&中所有元素的list
。 3并且不需要导入任何其他内容:
class C:
def get_data(self): return ['a', 'b']
d = {'a' : C(), 'b' : C()}
print([e for c in d.values() for e in c.get_data()]) # -> ['a', 'b', 'a', 'b']
在Python 2中,您可能希望使用d.itervalues()
而不是d.values()
,因为它会创建值的迭代器,而不是创建它们的临时列表(这是Python 3在{时自动执行的操作) {1}}方法调用)。