2017-07-20 105 views
1

的Python 3.6的Python:如果列表解析裏聲明發電機

考慮以下代碼:

from itertools import groupby 

result = [list(group) for key, group in groupby(range(5,15), key= lambda x: str(x)[0])] 

print(result) 

輸出:

[[5], [6], [7], [8], [9], [10, 11, 12, 13, 14]] 

我能夠過濾列表與len < 2名單內理解?

更新:

由於給出的兩個優秀的答案。我覺得這可能是值得的長凳標記

import timeit 

t1 = timeit.timeit(''' 
from itertools import groupby 
result = [group_list for group_list in (list(group) for key, group in groupby(range(5,15), key= lambda x: str(x)[0])) if len(group_list) >= 2] 
''', number=1000000) 
print(t1) 

t2 = timeit.timeit(''' 
from itertools import groupby 
list(filter(lambda group: len(group) >= 2, map(lambda key_group: list(key_group[1]),groupby(range(5,15), key=lambda x: str(x)[0])))) 
''', number=1000000) 
print(t2) 

結果:

8.74591397369441 
9.647086477861325 

貌似列表理解具有優勢。

回答

3

Yes

列表解析由包含後跟一個用於子句,則零個或多個for或if語句表達括號。結果將成爲一個新的列表,通過評估表達式在後面的for和if子句中產生。例如,這listcomp結合兩個列表的元素,如果他們不相等:

>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] 
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] 

和它等價於:

>>> combs = [] 
>>> for x in [1,2,3]: 
...  for y in [3,1,4]: 
...   if x != y: 
...    combs.append((x, y)) 
... 
>>> combs 
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)] 

注意的了,如果語句的順序是如何在同一這兩個片段。

由於調用list(group)兩次使用生成器表達式在特定的例子不工作(因爲它消耗由groupby產生髮電機),你可以在你的列表中理解引入一個臨時變量:

>>> [group_list for group_list in (list(group) for key, group in groupby(range(5,15), key= lambda x: str(x)[0])) if len(group_list) >= 2] 
[[10, 11, 12, 13, 14]] 

或者,用filtermaplist

>>> list(\ 
... filter(lambda group: len(group) >= 2,\ 
...  map(lambda key_group: list(key_group[1]),\ 
...  groupby(range(5,15), key=lambda x: str(x)[0])\ 
... )\ 
... )\ 
...) 
[[10, 11, 12, 13, 14]] 
+0

這是真棒!我知道必須有辦法! –