Na compreensão de lista Python é possível acessar o índice de itens?

89

Considere o seguinte código Python com o qual adiciono um novo list2todos os itens com índices de 1 a 3 de list1:

for ind, obj in enumerate(list1):
    if 4 > ind > 0:
        list2.append(obj)

Como você escreveria isso usando a compreensão de lista, se eu não tivesse acesso aos índices por meio de enumerar?

algo como:

list2 = [x for x in list1 if 4 > ind > 0]

mas como não tenho indnúmero, funcionaria?

list2 = [x for x in enumerate(list1) if 4 > ind > 0]
Pav Ametvic
fonte
3
Acho que seu caso de uso real é mais complexo, mas você poderia simplesmente cortar list1[1:4]aqui
wim
você quer dizer que eu poderia cortar a lista dentro da compreensão da lista? como [x for x in list1[1:4]]:?
Pav Ametvic
@PavAmetvic, não @wim significa que você pode simplesmente escreverlist2 = list1[1:4]
John La Rooy

Respostas:

177
list2 = [x for ind, x in enumerate(list1) if 4 > ind > 0]
Pavel Anossov
fonte
37

Se você usar enumerate, você fazer têm acesso ao índice:

list2 = [x for ind, x in enumerate(list1) if 4>ind>0]
BrenBarn
fonte
8

A menos que seu caso de uso real seja mais complicado, você deve apenas usar uma fatia da lista, conforme sugerido por @wim

>>> list1 = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']
>>> [x for ind, x in enumerate(list1) if 4 > ind > 0]
['one', 'two', 'three']
>>> list1[1:4]
['one', 'two', 'three']

Para casos mais complicados - se você não precisa realmente do índice - é mais fácil iterar sobre uma fatia ou um islice

list2 = [x*2 for x in list1[1:4]]

ou

from itertools import islice
list2 = [x*2 for x in islice(list1, 1, 4)]

Para pequenas fatias, o simples list1[1:4]. Se as fatias podem ficar muito grandes, pode ser melhor usar um islice para evitar copiar a memória

John La Rooy
fonte
obrigado, mas como eu quero realizar uma operação em 'x' dentro da compreensão (digamos x * x) antes de armazená-la na nova lista, parece que usar a fatia dentro da compreensão da lista é a melhor maneira! obrigado
Pav Ametvic
@PavAmetvic, ok esses casos ainda são simples o suficiente para não precisar de enumeração
John La Rooy