En la comprensión de la lista de Python, ¿es posible acceder al índice de elementos?

3 minutos de lectura

avatar de usuario
pav ametvic

Considere el siguiente código de Python con el que agrego un nuevo list2 todos los ítems con índices del 1 al 3 de list1:

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

¿Cómo escribiría esto usando la comprensión de lista, si no tengo acceso a los índices a través de la enumeración?

algo como:

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

pero como no tengo ind número, ¿funcionaría esto?

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

  • Supongo que su caso de uso real es más complejo, pero simplemente podría estar rebanando list1[1:4] aquí

    – Wim

    13 de febrero de 2013 a las 23:12

  • ¿Quieres decir que podría dividir la lista dentro de la comprensión de la lista? me gusta : [x for x in list1[1:4]] ?

    – Pav Ametvic

    13 de febrero de 2013 a las 23:31


  • @PavAmetvic, no @wim significa que solo puedes escribir list2 = list1[1:4]

    – John LaRooy

    13 de febrero de 2013 a las 23:59

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

Si utiliza enumeratehacer tener acceso al índice:

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

avatar de usuario
Juan La Rooy

A menos que su caso de uso real sea más complicado, solo debe usar un segmento de lista como lo sugiere @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 más complicados, si en realidad no necesita el índice, es más claro iterar sobre un segmento o un segmento.

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

o

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

Para rebanadas pequeñas, el simple list1[1:4]. Si los segmentos pueden llegar a ser bastante grandes, puede ser mejor usar un islice para evitar copiar la memoria.

  • gracias, pero dado que quiero realizar una operación en ‘x’ dentro de la comprensión (digamos x * x) antes de almacenarla dentro de la nueva lista, ¡parece que usar el segmento dentro de la comprensión de la lista es la mejor manera! Gracias

    – Pav Ametvic

    14 de febrero de 2013 a las 0:19

  • @PavAmetvic, está bien, esos casos siguen siendo lo suficientemente simples como para no necesitar enumeración

    – John LaRooy

    14 de febrero de 2013 a las 0:36

Para aquellos que se preguntan, puede almacenar fácilmente los índices coincidentes como resultado de la comprensión de la lista si su caso de uso lo requiere. Puede ser que necesite evaluar el valor de cada elemento de la lista para determinar si coincide con algún valor o patrón, y que solo desee obtener una lista de los índices coincidentes para un procesamiento posterior en lugar de los valores coincidentes.

Esto se puede hacer como se muestra a continuación:

>>> values = ['zero', 'one', 'two', 'three', 'four', 'five', 'six']
>>> search = ['one', 'three', 'five']
>>> matches = [i for i, x in enumerate(values) if x in search]
>>> print(matches)
[1, 3, 5]

La parte importante anterior es el uso de la [i for i, x in enumerate(l) if ...] patrón en la lista de comprensión, donde el índice i se está capturando en lugar del valor x que se lograría usando el más típico [x for x in l if ...] o el suplente [x for i, x in enumerate(l) if ...] patrones de comprensión de listas de enumeración.

¿Ha sido útil esta solución?