web-dev-qa-db-fra.com

Possibilité de retourner deux listes à partir d'une compréhension de liste?

Est-il possible de renvoyer deux listes à partir d'une compréhension de liste? Eh bien, cela ne fonctionne évidemment pas, mais quelque chose comme:

rr, tt = [i*10, i*12 for i in xrange(4)]

Donc rr et tt sont tous deux des listes avec les résultats de i*10 et i*12 respectivement. Merci beaucoup

42
LarsVegas
>>> rr,tt = Zip(*[(i*10, i*12) for i in xrange(4)])
>>> rr
(0, 10, 20, 30)
>>> tt
(0, 12, 24, 36)
67
jamylak

Il est préférable de créer deux listes de compréhension (du moins pour les longues listes). Sachez que la meilleure réponse est plus lente peut être encore plus lente que les boucles for traditionnelles. Les compréhensions de listes sont plus rapides et plus claires .

python -m timeit -n 100 -s 'rr=[];tt = [];' 'for i in range(500000): rr.append(i*10);tt.append(i*12)' 
10 loops, best of 3: 123 msec per loop

> python -m timeit -n 100 'rr,tt = Zip(*[(i*10, i*12) for i in range(500000)])' 
10 loops, best of 3: 170 msec per loop

> python -m timeit -n 100 'rr = [i*10 for i in range(500000)]; tt = [i*10 for i in range(500000)]' 
10 loops, best of 3: 68.5 msec per loop

Ce serait bien de voir des compréhensions de listes soutenant la création de plusieurs listes à la fois.

Cependant,

si vous pouvez profiter de l'utilisation d'une boucle traditionnelle (pour être précis, calculs intermédiaires), alors il est possible que vous serez mieux avec une boucle (ou un iterator/generator en utilisant yield). Voici un exemple:

$ python3 -m timeit -n 100 -s 'rr=[];tt=[];' "for i in (range(1000) for x in range(10000)): tmp = list(i); rr.append(min(tmp));tt.append(max(tmp))" 
100 loops, best of 3: 314 msec per loop

$ python3 -m timeit -n 100 "rr=[min(list(i)) for i in (range(1000) for x in range(10000))];tt=[max(list(i)) for i in (range(1000) for x in range(10000))]"
100 loops, best of 3: 413 msec per loop

Bien sûr, la comparaison dans ces cas est injuste ; dans l'exemple, le code et les calculs ne sont pas équivalents car dans la boucle traditionnelle un résultat temporaire est stocké (voir la variable tmp). Ainsi, la compréhension de liste fait beaucoup plus d'opérations internes (elle calcule la variable tmp deux fois !, mais elle n'est que 25% plus lente).

6
toto_tico

Il est possible pour une compréhension de liste de renvoyer plusieurs listes si les éléments sont des listes. Donc par exemple:

>>> x, y = [[] for x in range(2)]
>>> x
[]
>>> y
[]
>>>

L'astuce avec la fonction Zip ferait l'affaire, mais elle est en fait beaucoup plus simple et lisible si vous collectez simplement les résultats dans des listes avec une boucle.

1
Mariy