Python używa funkcji enumerate wewnątrz list

125

Załóżmy, że mam taką listę:

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

Aby uzyskać wydrukowane wartości wraz z ich indeksem, mogę użyć enumeratefunkcji Pythona w ten sposób

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

Teraz, kiedy próbuję użyć go wewnątrz a list comprehension, pojawia się ten błąd

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

Tak więc moje pytanie brzmi: jaki jest prawidłowy sposób używania rozumienia wyliczeń wewnątrz listy?

RanRag
źródło

Odpowiedzi:

166

Spróbuj tego:

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

Aby i,jlista działała, musisz umieścić ją w krotce. Alternatywnie, biorąc pod uwagę, że enumerate() już zwraca krotkę, możesz zwrócić ją bezpośrednio, bez wcześniejszego rozpakowywania:

[pair for pair in enumerate(mylist)]

Tak czy inaczej, zwracany wynik jest zgodny z oczekiwaniami:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Óscar López
źródło
4
Nie musi być krotką. Dowolne wyrażenie używające i oraz j, które zwraca wartość, zrobi
Alvaro
użycie wyliczania jest świetne, a co powiesz na uczynienie go bardziej wydajnym przy użyciu narzędzi itertools
Pramit
3
Wystarczy pamiętać, że krotka jest zbudowany przez , nie() . Zatem „umieszczanie i,jwewnątrz krotki” nie ma sensu, ponieważ i,jjuż jest krotką! Problem polega na tym, że parser kompilacji listy potrzebuje parens dla grupy instrukcji.
cowbert
46

Żeby było naprawdę jasne, nie ma to nic wspólnego ze enumerateskładnią rozumienia list, a wszystko to.

Ta lista zwraca listę krotek:

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

to lista nakazów:

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

lista list:

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

błąd składniowy:

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

Co jest niespójne (IMHO) i mylące ze składnią wyrażeń słownikowych:

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

I zestaw krotek:

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

Jak stwierdził Óscar López, możesz po prostu przekazać bezpośrednio wyliczoną krotkę:

>>> [t for t in enumerate('abcdef') ] 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f')]
Wilk
źródło
32

Lub, jeśli nie nalegasz na rozumienie listy:

>>> mylist = ["a","b","c","d"]
>>> list(enumerate(mylist))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Pillmuncher
źródło
12

Jeśli używasz długich list, ich rozumienie jest szybsze, nie wspominając o bardziej czytelnej formie.

~$ 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
beardc
źródło
2
+1 Nie testowałem tego, ale stawiam [t for t in enumerate(my list)]jest jeszcze szybszy.
wilk
11

Oto sposób, aby to zrobić:

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

Alternatywnie możesz:

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

Powodem, dla którego pojawił się błąd, był brak znaku () dookoła ii jutworzenie krotki.

Simeon Visser
źródło
6

Mów wyraźnie o krotkach.

[(i, j) for (i, j) in enumerate(mylist)]
Ignacio Vazquez-Abrams
źródło
0

Wszystkie świetne odpowiedzi. Wiem, że pytanie jest specyficzne dla wyliczenia, ale co powiesz na coś takiego, tylko z innej perspektywy

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

Staje się potężniejszy, jeśli trzeba iterować wiele list równolegle pod względem wydajności. Tylko myśl

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
Pramit
źródło