Python usando enumerar compreensão de lista interna

125

Vamos supor que eu tenha uma lista como esta:

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

Para obter os valores impressos junto com seu índice, posso usar a enumeratefunção do Python assim

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

Agora, quando eu tento usá-lo dentro de um, list comprehensionisso me dá esse erro

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

Então, minha pergunta é: qual é a maneira correta de usar enumerar a compreensão da lista interna?

RanRag
fonte

Respostas:

166

Tente o seguinte:

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

Você precisa i,jinserir uma tupla para que a compreensão da lista funcione. Como alternativa, como enumerate() retorna uma tupla, você pode devolvê-la diretamente sem descompactá-la primeiro:

[pair for pair in enumerate(mylist)]

De qualquer forma, o resultado retornado é o esperado:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]
Óscar López
fonte
4
Não é obrigatório ser uma tupla. Qualquer expressão usando i e j que retorna um valor fará
Alvaro
o uso da enumeração é ótimo, que tal torná-lo mais eficiente usando o itertools #
1128
3
Basta lembrar que uma tupla é construído pela , não o (). Portanto, "colocar i,jdentro de uma tupla" não faz sentido, pois i,jjá é uma tupla! O problema é que o analisador de compactação de lista precisa das parênteses para o grupo de instruções.
cowbert
46

Só para ficar bem claro, isso não tem nada a ver com enumeratee tudo a ver com a sintaxe de compreensão da lista.

Essa compreensão da lista retorna uma lista de tuplas:

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

esta é uma lista de ditados:

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

uma lista de listas:

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

um erro de sintaxe:

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

O que é inconsistente (IMHO) e confuso com a sintaxe de compreensão de dicionário:

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

E um conjunto de tuplas:

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

Como Óscar López afirmou, você pode simplesmente passar a tupla enumerada diretamente:

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

Ou, se você não insistir em usar uma compreensão de lista:

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

Se você estiver usando listas longas, parece que a compreensão da lista é mais rápida, sem mencionar mais legível.

~$ 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
barba
fonte
2
+1 Eu não testei, mas aposto que [t for t in enumerate(my list)]é ainda mais rápido.
o lobo
11

Aqui está uma maneira de fazer isso:

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

Como alternativa, você pode fazer:

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

A razão pela qual você recebeu um erro foi porque estava perdendo o () ie jpara torná-lo uma tupla.

Simeon Visser
fonte
6

Seja explícito sobre as tuplas.

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

Todos ótimos caras de resposta. Eu sei que a pergunta aqui é específica para enumeração, mas que tal algo assim, apenas outra perspectiva

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

Torna-se mais poderoso se for necessário repetir várias listas em paralelo em termos de desempenho. Apenas um pensamento

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