Python mit Aufzählung innerhalb des Listenverständnisses

125

Nehmen wir an, ich habe eine Liste wie diese:

mylist = ["a","b","c","d"]

Um die Werte zusammen mit ihrem Index zu drucken, kann ich die Python- enumerateFunktion wie folgt verwenden

>>> for i,j in enumerate(mylist):
...     print i,j
...
0 a
1 b
2 c
3 d
>>>

Wenn ich jetzt versuche, es in einem zu verwenden list comprehension, gibt es mir diesen Fehler

>>> [i,j for i,j in enumerate(mylist)]
  File "<stdin>", line 1
    [i,j for i,j in enumerate(mylist)]
           ^
SyntaxError: invalid syntax

Meine Frage lautet also: Wie wird die Aufzählung innerhalb des Listenverständnisses richtig verwendet?

RanRag
quelle

Antworten:

166

Versuche dies:

[(i, j) for i, j in enumerate(mylist)]

Sie müssen i,jein Tupel eingeben, damit das Listenverständnis funktioniert. Alternativ dazu gegeben , dass enumerate() bereits ein Tupel zurückgibt, können Sie es direkt zurück , ohne es zuerst zu auspacken:

[pair for pair in enumerate(mylist)]

In jedem Fall ist das Ergebnis, das zurückgegeben wird, wie erwartet:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Óscar López
quelle
4
Nicht zwingend erforderlich, um ein Tupel zu sein. Jeder Ausdruck mit i und j, der einen Wert zurückgibt, reicht aus
Alvaro
Die Verwendung der Aufzählung ist großartig. Wie wäre es mit einer effizienteren Verwendung von itertools
Pramit
3
Denken Sie daran, dass ein Tupel von der , nicht der gebaut wird (). " i,jIn ein Tupel stecken" macht also keinen Sinn, da i,jes bereits ein Tupel ist! Das Problem ist, dass der Listencomputer die Parens für die Anweisungsgruppe benötigt.
Cowbert
46

Um ganz klar zu sein, hat dies nichts enumeratemit der Syntax des Listenverständnisses zu tun.

Dieses Listenverständnis gibt eine Liste von Tupeln zurück:

[(i,j) for i in range(3) for j in 'abc']

Dies ist eine Liste von Diktaten:

[{i:j} for i in range(3) for j in 'abc']

eine Liste von Listen:

[[i,j] for i in range(3) for j in 'abc']

ein Syntaxfehler:

[i,j for i in range(3) for j in 'abc']

Was inkonsistent (IMHO) und verwirrend mit der Syntax des Wörterbuchverständnisses ist:

>>> {i:j for i,j in enumerate('abcdef')}
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}

Und eine Reihe von Tupeln:

>>> {(i,j) for i,j in enumerate('abcdef')}
set([(0, 'a'), (4, 'e'), (1, 'b'), (2, 'c'), (5, 'f'), (3, 'd')])

Wie Óscar López sagte, können Sie das Aufzählungstupel einfach direkt übergeben:

>>> [t for t in enumerate('abcdef') ] 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f')]
der Wolf
quelle
32

Oder wenn Sie nicht darauf bestehen, ein Listenverständnis zu verwenden:

>>> mylist = ["a","b","c","d"]
>>> list(enumerate(mylist))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Pillmuncher
quelle
12

Wenn Sie lange Listen verwenden, scheint das Listenverständnis schneller zu sein, ganz zu schweigen von der besseren Lesbarkeit.

~$ python -mtimeit -s"mylist = ['a','b','c','d']" "list(enumerate(mylist))"
1000000 loops, best of 3: 1.61 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[(i, j) for i, j in enumerate(mylist)]"
1000000 loops, best of 3: 0.978 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[t for t in enumerate(mylist)]"
1000000 loops, best of 3: 0.767 usec per loop
Bart
quelle
2
+1 Ich habe es nicht getestet, aber ich wette, es [t for t in enumerate(my list)]ist noch schneller.
Der Wolf
11

Hier ist eine Möglichkeit, dies zu tun:

>>> mylist = ['a', 'b', 'c', 'd']
>>> [item for item in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

Alternativ können Sie Folgendes tun:

>>> [(i, j) for i, j in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

Der Grund, warum Sie einen Fehler erhalten haben, war, dass Sie das () verpasst haben iund jes zu einem Tupel gemacht haben.

Simeon Visser
quelle
6

Seien Sie explizit über die Tupel.

[(i, j) for (i, j) in enumerate(mylist)]
Ignacio Vazquez-Abrams
quelle
0

Alles tolle Antwort Jungs. Ich weiß, dass die Frage hier spezifisch für die Aufzählung ist, aber wie wäre es mit so etwas, nur einer anderen Perspektive

from itertools import izip, count
a = ["5", "6", "1", "2"]
tupleList = list( izip( count(), a ) )
print(tupleList)

Es wird leistungsfähiger, wenn mehrere Listen in Bezug auf die Leistung parallel durchlaufen werden müssen. Nur ein Gedanke

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
Pramit
quelle