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
看起来列表理解有优势。
答案 0 :(得分:3)
列表推导由括号组成,括号中包含一个表达式,后跟一个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]]
或者,使用filter
,map
和list
:
>>> 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]]