2017-05-27 166 views
0

我有這樣的事情類的詞典:遍歷包含列表

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()]] 

內部循環將產生一個清單,不能被外部循環消化。

+1

什麼是外循環在做什麼?你不是隻想''v.get_data()for d.values()]''。輸出應該是什麼?請給[mcve]。 – jonrsharpe

+0

如果您使用python2.7,我會建議使用iteritems/itervalues,因爲它們需要較少的內存。 看到這個https://stackoverflow.com/questions/13998492/iteritems-in-python。 – otadmor

回答

4

你想要一個扁平化:

[e for _, v in d.items() for e in v.get_data()] 

注意循環的順序。

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'] 
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'] 
2

只需修改現有的表達 -

[item for sublist in [v.get_data() for _, v in d.items()] for item in sublist] 
0

不知道你的「迭代是什麼意思遍佈所有元素「,但根據您的問題中的代碼,以下內容將在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())。