【问题标题】:Iterate over dictionary of class containing a list迭代包含列表的类的字典
【发布时间】:2017-05-27 11:10:37
【问题描述】:
我有这样的事情:
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()]]
内层循环会产生一个列表列表,外层循环无法消化。
【问题讨论】:
标签:
python
list-comprehension
【解决方案1】:
你想要一个扁平化:
[e for _, v in d.items() for e in v.get_data()]
注意循环的顺序。
【解决方案2】:
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']
【解决方案3】:
只需修改您现有的表达式 -
[item for sublist in [v.get_data() for _, v in d.items()] for item in sublist]
【解决方案4】:
@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']
【解决方案5】:
不确定“遍历所有元素”是什么意思,但根据您问题中的代码,以下内容将创建 Python 2 和 3 中所有元素的list,并且不需要导入任何内容其他:
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 在调用 values() 方法时自动执行的操作)。