简体   繁体   English

Python:如果语句内部列表理解发生器

[英]Python: If statement inside list comprehension on a generator

Python 3.6 Python 3.6

Consider this code: 考虑以下代码:

from itertools import groupby

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

print(result)

outputs: 输出:

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

Can I filter out the lists with len < 2 inside the list comprehension? 我可以在列表理解中过滤掉len < 2的列表吗?

Update: 更新:

Due to the two excellent answers given. 由于给出了两个优秀的答案。 I felt it might be worth a bench mark 我觉得它可能值得一个替补标记

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) 

Results: 结果:

8.74591397369441
9.647086477861325

Looks like the list comprehension has an edge. 看起来列表理解有优势。

Yes

A list comprehension consists of brackets containing an expression followed by a for clause, then zero or more for or if clauses. 列表推导由括号组成,括号中包含一个表达式,后跟一个for子句,然后是零个或多个for或if子句。 The result will be a new list resulting from evaluating the expression in the context of the for and if clauses which follow it. 结果将是一个新列表,该列表是通过在其后面的for和if子句的上下文中计算表达式得到的。 For example, this listcomp combines the elements of two lists if they are not equal: 例如,如果列表不相等,则此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)] 

and it's equivalent to: 它相当于:

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

Note how the order of the for and if statements is the same in both these snippets. 请注意这两个片段中for和if语句的顺序是如何相同的。

Since calling list(group) twice doesn't work in your particular example (as it consumes the generator yielded by groupby ), you can introduce a temporary variable in your list comprehension by using a generator expression: 由于调用list(group)两次在您的特定示例中不起作用(因为它使用由groupby生成的生成器),您可以使用生成器表达式在列表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]]

Alternately, using filter , map , and list : 或者,使用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]]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM