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

时间:2017-07-20 03:42:53

标签: python list list-comprehension

Python 3.6

考虑以下代码:

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

看起来列表理解有优势。

1 个答案:

答案 0 :(得分:3)

Yes

  

列表推导由括号组成,括号中包含一个表达式,后跟一个for子句,然后是零个或多个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)]
     

请注意这两个片段中for和if语句的顺序是否相同。

由于两次调用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]]