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?

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

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

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

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

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.



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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.