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.