2017-07-20 1 views
1

Python 3.6Python: Si instruction à l'intérieur la compréhension de la liste sur un générateur

Considérez ce code:

from itertools import groupby 

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

print(result) 

sorties:

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

Puis-je filtrer les listes avec len < 2 dans la liste compréhension?

Mise à jour:

En raison des deux excellentes réponses. Je sentais qu'il pourrait être utile une marque de banc

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) 

Résultats:

8.74591397369441 
9.647086477861325 

ressemble à la compréhension de la liste a un bord.

Répondre

3

Yes

Une compréhension de liste se compose de supports contenant une expression suivie d'une clause pour, puis zéro ou plus ou si pour articles. Le résultat sera une nouvelle liste résultant de l'évaluation de l'expression dans le contexte des clauses for et if qui la suivent. Par exemple, ce listcomp combine les éléments de deux listes si elles ne sont pas égaux:

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

et il est équivalent à:

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

Notez comment l'ordre du et si des déclarations est le même ces deux extraits.

Depuis l'appel list(group) deux fois ne fonctionne pas dans votre exemple particulier (car il consomme le générateur donné par groupby), vous pouvez introduire une variable temporaire dans votre compréhension de la liste en utilisant une expression du générateur:

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

Alternativement, en utilisant filter, map et 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]] 
+0

C'est génial! Je savais qu'il devait y avoir un moyen! –