[英]List Comprehension of Lists Nested in Dictionaries
我有一個字典,其中每個值都是一個列表,如下所示:
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
。 我嘗試的其他所有內容都使用了某種非法語法。
我怎么能表現出這樣的理解力呢?
循環遍歷返回的列表(直接在字典上循環也為您提供鍵):
[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()
函數和合適的生成器表達式就是這樣:
any('a' in lst for lst in dictA.itervalues())
一旦dictA
中'a'
任何值列出'a'
,就會返回True
並且盡早停止循環.itervalues()
。
如果您實際上正在檢查成員身份(您的a in...
示例),您可以將其重寫為:
if any('a' in val for val in dictA.itervalues()):
# do something
如果實際上不需要,則可以節省必須壓縮列表。
在這種特殊情況下,您可以使用嵌套理解:
[value for key in dictA.keys() for value in dictA[key]]
但總的來說,如果你已經想出如何將某些東西變成嵌套列表,你可以使用chain.from_iterable
來展平任何嵌套的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
相同的for key in dictA
,除了在舊版本的Python中,它會浪費時間和內存來創建一個額外的鍵列表。 正如文檔所說, dict
上的iter
與iterkeys
相同。
所以,在上面的所有版本中,最好只in dictA
使用。
在簡單的代碼中只是為了理解這可能會有所幫助
ListA=[]
dictA = {1:['a','b','c'],2:['d','e']}
for keys in dictA:
for values in dictA[keys]:
ListA.append(values)
你可以做一些像..
output_list = []
[ output_list.extend(x) for x in {1:['a','b','c'],2:['d','e']}.values()]
output_list將是['a','b','c','d','e']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.