¿Accediendo al índice en bucles 'for'?

4265

¿Cómo accedo al índice en un forbucle como el siguiente?

ints = [8, 23, 45, 12, 78]
for i in ints:
    print('item #{} = {}'.format(???, i))

Quiero obtener esta salida:

item #1 = 8
item #2 = 23
item #3 = 45
item #4 = 12
item #5 = 78

Cuando lo recorro usando un forbucle, ¿cómo accedo al índice del bucle, de 1 a 5 en este caso?

2
  • 62
    Tenga en cuenta que los índices en Python comienzan desde 0, por lo que los índices de su lista de ejemplo son 0 a 4, no 1 a 5 2 oct 2018 a las 16:54
  • 1
    @JoanVenge esta es una gran pregunta que he tenido MUCHAS VECES. Y el comentario anterior dice que está basado en un índice cero (por lo tanto, los humanos contamos de 1 a 3 como 1,2,3, pero las computadoras cuentan como 0,1,2 (entonces, un tamaño de 3, por ejemplo, es [0,1 , 2] (0 cuenta como 1)) Y, las respuestas de esta pregunta a continuación también son: Brillante. ¡Gracias por esto! 23 de marzo a las 12:42
7186
+500

El uso de una variable de estado adicional, como una variable de índice (que normalmente usaría en lenguajes como C o PHP), se considera no pitónico.

La mejor opción es usar la función incorporada enumerate(), disponible tanto en Python 2 como en 3:

for idx, val in enumerate(ints):
    print(idx, val)

Consulte PEP 279 para obtener más información.

5
  • 90
    Como Aaron señala a continuación, use start = 1 si desea obtener 1-5 en lugar de 0-4.
    clozach
    31/03/18 a las 22:16
  • 5
    ¿ enumerateNo incurre en otra sobrecarga? 17/10/19 a las 23:03
  • 2
    @ TheRealChx101 de acuerdo con mis pruebas (Python 3.6.3) la diferencia es insignificante y, a veces, incluso a favor de enumerate. 7 feb.20 a las 12:18
  • 3
    @ TheRealChx101: es menor que la sobrecarga de recorrer un bucle rangee indexar cada vez, y menor que rastrear y actualizar manualmente el índice por separado. enumeratecon el desempaquetado está muy optimizado (si los tuplemensajes de correo electrónico se descomprimen en nombres como en el ejemplo proporcionado, reutiliza lo mismo en tuplecada bucle para evitar incluso el costo de la búsqueda en la lista libre, tiene una ruta de código optimizada para cuando el índice encaja con un rendimiento ssize_teconómico en -registrar matemáticas, omitiendo las operaciones matemáticas de nivel de Python, y evita indexar lista nivel de Python, que es más caro de lo que piensas). 6 oct.20 a las 18:19
  • 1
    @MikeHordecki ¡Esta es solo una respuesta ## brillante! ¡Gracias por esto! La pregunta tiene más de 12 años y esta respuesta funciona perfectamente. 12 de marzo a las 9:39
943

Using a for loop, how do I access the loop index, from 1 to 5 in this case?

Úselo enumeratepara obtener el índice con el elemento mientras itera:

for index, item in enumerate(items):
    print(index, item)

Y tenga en cuenta que los índices de Python comienzan en cero, por lo que obtendría de 0 a 4 con lo anterior. Si desea el recuento, de 1 a 5, haga esto:

count = 0 # in case items is empty and you need it after the loop
for count, item in enumerate(items, start=1):
    print(count, item)

Flujo de control unidiomático

Lo que está pidiendo es el equivalente Pythonic de lo siguiente, que es el algoritmo que la mayoría de los programadores de lenguajes de nivel inferior usarían:

index = 0            # Python's indexing starts at zero
for item in items:   # Python's for loops are a "for each" loop 
    print(index, item)
    index += 1

O en idiomas que no tienen un bucle for-each:

index = 0
while index < len(items):
    print(index, items[index])
    index += 1

oa veces más comúnmente (pero unidiomáticamente) que se encuentra en Python:

for index in range(len(items)):
    print(index, items[index])

Usar la función enumerar

La enumeratefunción de Python reduce el desorden visual al ocultar la contabilidad de los índices y encapsular el iterable en otro iterable (un enumerateobjeto) que produce una tupla de dos elementos del índice y el elemento que proporcionaría el iterable original. Eso se ve así:

for index, item in enumerate(items, start=0):   # default is zero
    print(index, item)

Esta muestra de código es bastante bien el ejemplo canónico de la diferencia entre el código idiomático de Python y el código que no lo es. El código idiomático es Python sofisticado (pero no complicado), escrito de la forma en que fue diseñado para ser utilizado. Los diseñadores del lenguaje esperan código idiomático, lo que significa que normalmente este código no solo es más legible, sino también más eficiente.

Conseguir un recuento

Incluso si no necesita índices sobre la marcha, pero necesita un recuento de las iteraciones (a veces deseables) con las que puede comenzar 1y el número final será su recuento.

count = 0 # in case items is empty
for count, item in enumerate(items, start=1):   # default is zero
    print(item)

print('there were {0} items printed'.format(count))

El recuento parece ser más lo que pretendes pedir (a diferencia del índice) cuando dijiste que querías de 1 a 5.


Desglosando: una explicación paso a paso

Para desglosar estos ejemplos, digamos que tenemos una lista de elementos sobre los que queremos iterar con un índice:

items = ['a', 'b', 'c', 'd', 'e']

Ahora pasamos este iterable a enumerar, creando un objeto enumerado:

enumerate_object = enumerate(items) # the enumerate object

Podemos sacar el primer elemento de este iterable que obtendríamos en un bucle con la nextfunción:

iteration = next(enumerate_object) # first iteration from enumerate
print(iteration)

Y vemos que obtenemos una tupla de 0, el primer índice y 'a', el primer elemento:

(0, 'a')

podemos usar lo que se conoce como " desempaquetado de secuencia " para extraer los elementos de esta tupla de dos:

index, item = iteration
#   0,  'a' = (0, 'a') # essentially this.

y cuando inspeccionamos index, encontramos que se refiere al primer índice, 0, y itemse refiere al primer punto, 'a'.

>>> print(index)
0
>>> print(item)
a

Conclusión

  • Los índices de Python comienzan en cero
  • Para obtener estos índices de un iterable a medida que lo recorre, use la función enumerar
  • El uso de enumerate de forma idiomática (junto con el desempaquetado de tuplas) crea un código que es más legible y fácil de mantener:

Entonces haz esto:

for index, item in enumerate(items, start=0):   # Python indexes start at zero
    print(index, item)
4
  • 1
    ¿ Funciona el ejemplo " Obtener un recuento " cuando itemsestá vacío?
    Bergi
    22/02/20 a las 15:36
  • Estoy enviando datos usando ajax a las vistas de Django como una matriz en forma de dos valores en una variable legData con valores como [1406, 1409]. Si imprimo en la consola usando print(legData), la salida es [1406,1409] . Sin embargo, si trato de analizar los valores individuales de la lista como for idx, xLeg in enumerate(legData): print(idx, xLeg), me da una salida de enteros individuales como [, 1, 4, 0, 6, y así sucesivamente contra los índices 0, 1, 2, 3, 4 etc. (sí, los corchetes y la coma también se generan como si fueran parte de los datos en sí ). ¿Qué va mal aquí? 15 de mayo de 2020 a las 15:51
  • @ user12379095 probablemente tenga los datos en el tipo incorrecto (una cadena) y necesite convertirlos en una lista real de números en lugar de una cadena. Eso es algo fuera de tema aquí, elimine su comentario y marque el mío para que se elimine como ya no es necesario cuando vea esto. 15 de mayo de 2020 a las 23:01
  • 1
    @Bergi: No lo hará, pero puede simplemente agregar count = 0antes del ciclo para asegurarse de que tenga un valor (y es el correcto cuando el ciclo nunca se asigna count, ya que por definición no había elementos). 6 oct.20 a las 18:21
183

Es bastante simple comenzar desde 1otra cosa que no sea 0:

for index, item in enumerate(iterable, start=1):
   print index, item  # Used to print in python<3.x
   print(index, item) # Mirate print() after 3.x+
   
4
  • 11
    La pregunta era sobre índices de listas; dado que comienzan desde 0, no tiene mucho sentido comenzar desde otro número, ya que los índices estarían mal (sí, el OP también lo dijo mal en la pregunta). De lo contrario, llamar a la variable que es tupla de index, itemjust indexes muy engañoso, como señaló. Solo usa for index, item in enumerate(ints). 18 de marzo de 2016 a las 9:18
  • 1
    Es mejor encerrar el índice entre paréntesis como (índice), funcionará en las versiones 2 y 3 de Python.
    hygull
    2 de enero de 2018 a las 11:31
  • 1
    @AnttiHaapala La razón, supongo, es que la salida esperada de la pregunta comienza en el índice 1 en lugar de 0
    pushkin
    30 nov 2018 a las 18:24
  • @hygull: Convertirse indexen (index)no cambiará nada ni en Py2 ni en Py3. Siento que tal vez estás pensando en el cambio a print; la única forma de hacer que eso funcione tanto en Py2 como en Py3 es agregar from __future__ import print_functiona la parte superior de su archivo para obtener un estilo Py3 consistente printy cambiar printa print(index, item). O leyó una edición anterior de la pregunta cuándo indexestaba el original tuple, no descomprimido en dos nombres, pero los paréntesis aún no cambian nada si no puede descomprimir. 6/10/20 a las 18:23
102
for i in range(len(ints)):
   print(i, ints[i]) # print updated to print() in Python 3.x+ 
8
  • 10
    Probablemente debería ser xrangepara versiones anteriores a 3.0. 6 feb 09 a las 22:52
  • 52
    Utilice enumerar en su lugar 1 de agosto de 2015 a las 21:28
  • 4
    Para Python 2.3 anterior, use la función incorporada enumerate ya que es más Pythonic. 15 de marzo de 2017 a las 6:31
  • Enumerar no siempre es mejor, depende de los requisitos de la aplicación. En mi situación actual, las relaciones entre las longitudes de los objetos son significativas para mi aplicación. Aunque comencé a usar enumerate, cambié a este enfoque para evitar tener que escribir lógica para seleccionar qué objeto enumerar.
    adg
    31 de marzo de 2017 a las 23:18
  • 4
    @adg No veo cómo evitar enumerateguarda ninguna lógica; todavía tienes que seleccionar con qué objeto indexar i, ¿no?
    chepner
    15 de septiembre de 2017 a las 23:15
51

Como es la norma en Python, hay varias formas de hacer esto. En todos los ejemplos, suponga:lst = [1, 2, 3, 4, 5]

1. Usar enumerate ( considerado más idiomático )

for index, element in enumerate(lst):
    # do the things that need doing here

Esta es también la opción más segura en mi opinión porque se ha eliminado la posibilidad de entrar en recursividad infinita. Tanto el elemento como su índice se mantienen en variables y no es necesario escribir ningún código adicional para acceder al elemento.

2. Creando una variable para contener el índice ( usandofor )

for index in range(len(lst)):   # or xrange
    # you will have to write extra code to get the element

3. Creando una variable para contener el índice ( usandowhile )

index = 0
while index < len(lst):
    # you will have to write extra code to get the element
    index += 1  # escape infinite recursion

4. Siempre hay otra forma

Como se explicó anteriormente, hay otras formas de hacer esto que no se han explicado aquí y pueden incluso aplicarse más en otras situaciones. por ejemplo, usando itertools.chaincon para. Maneja los bucles anidados mejor que los otros ejemplos.

0
36

De forma anticuada:

for ix in range(len(ints)):
    print(ints[ix])

Comprensión de listas:

[ (ix, ints[ix]) for ix in range(len(ints))]

>>> ints
[1, 2, 3, 4, 5]
>>> for ix in range(len(ints)): print ints[ix]
... 
1
2
3
4
5
>>> [ (ix, ints[ix]) for ix in range(len(ints))]
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
>>> lc = [ (ix, ints[ix]) for ix in range(len(ints))]
>>> for tup in lc:
...     print(tup)
... 
(0, 1)
(1, 2)
(2, 3)
(3, 4)
(4, 5)
>>> 
5
  • 4
    Esto no está mal y se usa en C / C ++ y otros. Se considera no pitónico, pero también se puede usar en Python. Como soluciones simples que lo descomponen en la fuente: +
    user6734503
    29/07/18 a las 20:57
  • Algunos extremistas de las pitones dirían, no hagas esto. Pero lo dije solo para indicar que hay más de una forma posible
    user6734503
    30/07/18 a las 13:51
  • niiice, algo que los usuarios de c pueden entender
    Ahmad
    29 dic.20 a las 0:15
  • 1
    "Pasado de moda" no significa en realidad "incorrecto" 29/12/20 a las 15:36
  • 1
    @CharlieMartin ¡ESTA fue una respuesta GENIAL! Muchas gracias por publicar esto; ¡Ayudó MUCHO ! [+10/10] 18 de marzo a las 11:35
33

Acceso a índices y evaluación comparativa de rendimiento de enfoques

La forma más rápida de acceder a índices de lista dentro del ciclo en Python 3.7 es usar el método enumerate para listas pequeñas, medianas y grandes.

Consulte los diferentes enfoques que se pueden usar para iterar sobre la lista y el valor del índice de acceso y sus métricas de rendimiento (que supongo que serían útiles para usted) en los ejemplos de código a continuación:

# Using range
def range_loop(iterable):
    for i in range(len(iterable)):
        1 + iterable[i]

# Using enumerate
def enumerate_loop(iterable):
    for i, val in enumerate(iterable):
        1 + val

# Manual indexing
def manual_indexing_loop(iterable):
    index = 0
    for item in iterable:
        1 + item
        index += 1

Consulte las métricas de rendimiento de cada método a continuación:

from timeit import timeit

def measure(l, number=10000):
    print("Measure speed for list with %d items" % len(l))
    print("range: ", timeit(lambda :range_loop(l), number=number))
    print("enumerate: ", timeit(lambda :enumerate_loop(l), number=number))
    print("manual_indexing: ", timeit(lambda :manual_indexing_loop(l), number=number))

# Measure speed for list with 1000 items
measure(range(1000))
# range:  1.161622366
# enumerate:  0.5661940879999996
# manual_indexing:  0.610455682

# Measure speed for list with 100000 items
measure(range(10000))
# range:  11.794482958
# enumerate:  6.197628574000001
# manual_indexing:  6.935181098000001

# Measure speed for list with 10000000 items
measure(range(10000000), number=100)
# range:  121.416859069
# enumerate:  62.718909123
# manual_indexing:  69.59575057400002

Como resultado, el enumeratemétodo using es el método más rápido para la iteración cuando el índice lo necesita.

Añadiendo algunos enlaces útiles a continuación:

3
  • 7
    "La legibilidad cuenta" La diferencia de velocidad en el rango pequeño <1000 es insignificante. Es un 3% más lento en una métrica de tiempo que ya es pequeña.
    user4805123
    4 de marzo de 2017 a las 0:08
  • ¿Qué tal actualizar la respuesta a Python 3?
    Georgy
    22 de mayo de 2019 a las 14:20
  • @Georgy tiene sentido, en Python 3.7 enumerate es el ganador total :) 16/06/20 a las 9:22
16

Esto es lo que obtiene cuando accede al índice en forbucles:

for i in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i in enumerate(items):
    print("index/value", i)

Resultado:

# index/value (0, 8)
# index/value (1, 23)
# index/value (2, 45)
# index/value (3, 12)
# index/value (4, 78)

for i, val in enumerate(items): print(i, val)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i, "for value", val)

Resultado:

# index 0 for value 8
# index 1 for value 23
# index 2 for value 45
# index 3 for value 12
# index 4 for value 78

for i, val in enumerate(items): print(i)

items = [8, 23, 45, 12, 78]

for i, val in enumerate(items):
    print("index", i)

Resultado:

# index 0
# index 1
# index 2
# index 3
# index 4
0
14

En primer lugar, los índices serán de 0 a 4. Los lenguajes de programación comienzan a contar desde 0; no lo olvide o se encontrará con una excepción de índice fuera de límites. Todo lo que necesita en el ciclo for es una variable que cuente de 0 a 4 así:

for x in range(0, 5):

Tenga en cuenta que escribí de 0 a 5 porque el ciclo se detiene un número antes del máximo. :)

Para obtener el valor de un índice, utilice

list[index]
13

Según esta discusión: http://bytes.com/topic/python/answers/464012-objects-list-index

Iteración del contador de bucle

El idioma actual para recorrer los índices hace uso de la rangefunción incorporada:

for i in range(len(sequence)):
    # work with index i

El bucle sobre los elementos y los índices se puede lograr mediante el antiguo idioma o mediante el uso de la nueva zipfunción incorporada:

for i in range(len(sequence)):
    e = sequence[i]
    # work with index i and element e

o

for i, e in zip(range(len(sequence)), sequence):
    # work with index i and element e

a través de http://www.python.org/dev/peps/pep-0212/

3
12

Puedes hacerlo con este código:

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value

Use este código si necesita restablecer el valor del índice al final del ciclo:

ints = [8, 23, 45, 12, 78]
index = 0

for value in (ints):
    index +=1
    print index, value
    if index >= len(ints)-1:
        index = 0
12

Si nums = [1, 2, 3, 4, 5]tuviera que iterar lo haría

for i, num in enumerate(nums, start=1):
    print(i, num)

O obtenga la longitud como l = len(nums)

for i in range(l):
    print(i+1, nums[i])
0
11

La mejor solución para este problema es utilizar la enumeratefunción incorporada.

enumeratedevuelve un tuple, donde el primer valor es el índice y el segundo valor es el elemento de la lista en ese índice.

In [1]: ints = [8, 23, 45, 12, 78]

In [2]: for idx, val in enumerate(ints):
   ...:         print(idx, val)
   ...:     
(0, 8)
(1, 23)
(2, 45)
(3, 12)
(4, 78)
10

En su pregunta, escribe "¿cómo accedo al índice de bucle, de 1 a 5 en este caso?"

Sin embargo, el índice de una lista se ejecuta desde cero. Entonces, necesitamos saber si lo que realmente desea es el índice y el elemento para cada elemento en una lista, o si realmente desea números que comiencen desde 1. Afortunadamente, en Python, es fácil hacer una o ambas.

Primero, para aclarar, la enumeratefunción devuelve iterativamente el índice y el elemento correspondiente para cada elemento de una lista.

alist = [1, 2, 3, 4, 5]

for n, a in enumerate(alist):
    print("%d %d" % (n, a))

El resultado de lo anterior es entonces,

0 1
1 2
2 3
3 4
4 5

Tenga en cuenta que el índice se ejecuta desde 0. Este tipo de indexación es común entre los lenguajes de programación modernos, incluidos Python y C.

Si desea que su bucle abarque una parte de la lista, puede usar la sintaxis estándar de Python para una parte de la lista. Por ejemplo, para recorrer desde el segundo elemento de una lista hasta el último elemento, pero sin incluirlo, puede utilizar

for n, a in enumerate(alist[1:-1]):
    print("%d %d" % (n, a))

Tenga en cuenta que una vez más, el índice de salida va desde 0,

0 2
1 3
2 4

Eso nos lleva al start=ncambio de enumerate(). Esto simplemente compensa el índice, de manera equivalente, puede simplemente agregar un número al índice dentro del ciclo.

for n, a in enumerate(alist, start=1):
    print("%d %d" % (n, a))

para lo cual la salida es

1 1
2 2
3 3
4 4
5 5
6

También puedes probar esto:

data = ['itemA.ABC', 'itemB.defg', 'itemC.drug', 'itemD.ashok']
x = []
for (i, item) in enumerate(data):
      a = (i, str(item).split('.'))
      x.append(a)
for index, value in x:
     print(index, value)

La salida es

0 ['itemA', 'ABC']
1 ['itemB', 'defg']
2 ['itemC', 'drug']
3 ['itemD', 'ashok']
6

Si no hay un valor duplicado en la lista:

for i in ints:
    indx = ints.index(i)
    print(i, indx)
2
  • 2
    Tenga en cuenta que no se debe utilizar la primera opción, ya que solo funciona correctamente cuando cada elemento de la secuencia es único. 19/12/18 a las 14:05
  • 4
    La primera opción es O (n²), una idea terrible. Si su lista tiene 1000 elementos, le llevará literalmente 1000 veces más que usarla enumerate. Deberías eliminar esta respuesta.
    Boris
    20/04/19 a las 10:24
4

Puedes usar el indexmétodo

ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]

EDITAR Resaltado en el comentario de que este método no funciona si hay duplicados en ints, el método a continuación debería funcionar para cualquier valor en ints:

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup[0] for tup in enumerate(ints)]

O alternativamente

ints = [8, 8, 8, 23, 45, 12, 78]
inds = [tup for tup in enumerate(ints)]

si desea obtener tanto el índice como el valor intscomo una lista de tuplas.

Utiliza el método de enumerateen la respuesta seleccionada a esta pregunta, pero con comprensión de lista, haciéndolo más rápido con menos código.

0
4

Respuesta simple usando While Loop:

arr = [8, 23, 45, 12, 78]
i = 0
while i < len(arr):
    print("Item ", i + 1, " = ", arr[i])
    i += 1

Producción:

ingrese la descripción de la imagen aquí

2

Para imprimir la tupla de (índice, valor) en la comprensión de la lista mediante un forbucle:

ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]

Producción:

[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]
1

Esto sirve al propósito bastante bien:

list1 = [10, 'sumit', 43.21, 'kumar', '43', 'test', 3]
for x in list1:
    print('index:', list1.index(x), 'value:', x)
2
  • 6
    Esto se desglosará si hay elementos repetidos en la lista, ya index()que buscará la primera aparición de x, sin mencionar el tiempo O ( n ^ 2 ) requerido para buscar cada elemento. 15 de mayo de 2018 a las 17:17
  • totalmente de acuerdo en que no funcionará para elementos duplicados en la lista. Después de todo, también estoy aprendiendo Python. 6/06/18 a las 10:16
1

Simplemente puede usar una variable como countpara contar el número de elementos en la lista:

ints = [8, 23, 45, 12, 78]
count = 0
for i in ints:
    count = count + 1
    print('item #{} = {}'.format(count, i))
1

Puede usar enumerate para iterar sobre la lista y usarlo, start=1ya que estará predeterminado en 0, lo que significa que comenzaría a contar en 0.

Aquí hay un ejemplo:

for index,val in enumerate(ints,start=1):
     print(f"item #{index} = {val}")

Además, el uso de f-stringses una forma rápida de obtener la salida solicitada y es más legible, ya que puede pasar index y val a {} -placeholder directamente.

Producción:

item #1 = 8
item #2 = 23
item #3 = 45
item #4 = 12
item #5 = 78
5
  • 1
    Si bien esto responde correctamente a la pregunta, solo replica la información que ya se proporcionó en esta respuesta de seis años de edad altamente votada: stackoverflow.com/a/28072982/3216427 Si está tratando de agregar nueva información a esta pregunta anterior, explique qué es lo que está tratando de contribuir y cómo esta respuesta mejora la información que ya se encuentra aquí.
    joanis
    10 de junio a las 16:22
  • sí, lo hice ... quería mostrar el uso de la cadena f aquí
    Purnima
    10 de junio a las 20:28
  • 1
    Ah, está bien, entonces vale la pena agregarlo aquí. Le sugiero que agregue una oración de introducción diciendo eso. Es menos probable que obtenga votos negativos si lo hace o que elimine su respuesta.
    joanis
    10 de junio a las 23:05
  • Para referencia, consulte ¿Qué es la impresión (f “…”) .
    showdev
    11 de junio a las 0:19
  • ok ... explicación agregada.
    Purnima
    12 de junio a las 2:57
0

Use enumerate para iterar sobre la lista

ints = [8, 23, 45, 12, 78]
for idx,val in enumerate(ints):
    print('item #{} = {}'.format(idx+1, val))

Producción:

item #1 = 8
item #2 = 23
item #3 = 45
item #4 = 12
item #5 = 78