Python usa enumerare la comprensione dell'elenco all'interno


125

Supponiamo di avere un elenco come questo:

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

Per ottenere i valori stampati insieme al loro indice, posso usare la enumeratefunzione di Python in questo modo

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

Ora, quando provo ad usarlo all'interno di un list comprehensionmi dà questo errore

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

Quindi, la mia domanda è: qual è il modo corretto di usare la comprensione dell'elenco all'interno degli elenchi?

Risposte:


166

Prova questo:

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

Devi inserire i,juna tupla affinché la comprensione dell'elenco funzioni. In alternativa, dato che restituisce enumerate() già una tupla, puoi restituirla direttamente senza decomprimerla prima:

[pair for pair in enumerate(mylist)]

In entrambi i casi, il risultato che viene restituito è come previsto:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

4
Non è obbligatorio essere una tupla. Qualsiasi espressione che usa i e j che restituisce un valore farà
Alvaro il

l'uso dell'enumerazione è fantastico, che ne dici di renderlo più efficiente usando itertools
Pramit

3
Basta ricordare che una tupla è costruita dal , non il (). Quindi "mettere i,jdentro una tupla" non ha senso, poiché i,jè già una tupla! Il problema è che il parser dell'elenco comp necessita delle parentesi per il gruppo di istruzioni.
cowbert,

46

Giusto per essere veramente chiari, questo non ha nulla a che fare con enumeratetutto e tutto con la sintassi di comprensione dell'elenco.

Questa comprensione dell'elenco restituisce un elenco di tuple:

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

questo un elenco di dicts:

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

un elenco di elenchi:

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

un errore di sintassi:

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

Che è incoerente (IMHO) e confuso con la sintassi di comprensione del dizionario:

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

E una serie di tuple:

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

Come affermato da Óscar López, puoi semplicemente passare direttamente la tupla enumerata:

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

32

Oppure, se non insisti nell'usare una comprensione dell'elenco:

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

12

Se stai usando elenchi lunghi, sembra che la comprensione dell'elenco sia più veloce, per non dire più leggibile.

~$ 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 Non l'ho provato, ma scommetto che [t for t in enumerate(my list)]è ancora più veloce.
il lupo

11

Ecco un modo per farlo:

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

In alternativa, puoi fare:

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

Il motivo per cui hai ricevuto un errore è che ti mancava il () in giro ie jper renderlo una tupla.



0

Ottima risposta ragazzi. So che la domanda qui è specifica dell'enumerazione, ma che ne dici di qualcosa del genere, solo un'altra prospettiva

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

Diventa più potente se si devono iterare più liste in parallelo in termini di prestazioni. Solo un pensiero

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.