2017-07-20 106 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

这是真棒!我知道必须有办法! –