¿Accediendo al índice en bucles 'for'?
Frecuentes
Visto 2,412 equipos
3987
¿Cómo accedo al índice en un for
bucle 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 for
loop, ¿cómo accedo al índice de loop, de 1 a 5 en este caso?
20 Respuestas
6729
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 utilizar la función incorporada enumerate()
, disponible en Python 2 y 3:
for idx, val in enumerate(ints):
print(idx, val)
Fin del retiro PEP 279 para más.
Respondido el 17 de Septiembre de 16 a las 11:09
Como Aaron señala a continuación, use start = 1 si desea obtener 1-5 en lugar de 0-4. - clozach
¿Afecta la regulación de la enumerate
no incurrir en otra sobrecarga? - ElRealChx101
@ TheRealChx101 de acuerdo con mis pruebas (Python 3.6.3) la diferencia es insignificante y, a veces, incluso a favor de enumerate
. - Błotosmętek
@ TheRealChx101: Es menor que la sobrecarga de recorrer un range
e indexando cada vez, y menor que el seguimiento manual y la actualización del índice por separado. enumerate
con el desembalaje está muy optimizado (si el tuple
s se descomprimen en nombres como en el ejemplo proporcionado, reutiliza el mismo tuple
cada 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 ssize_t
que realiza matemáticas de registro baratas, sin pasar por las operaciones matemáticas de nivel de Python, y evita la indexación de list
a nivel de Python, que es más caro de lo que piensas). - ShadowRanger
879
Usando un bucle for, ¿cómo accedo al índice de bucle, de 1 a 5 en este caso?
Utilice la herramienta enumerate
para 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:
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
Python enumerate
función reduce el desorden visual ocultando la contabilidad de los índices y encapsulando el iterable en otro iterable (un enumerate
object) 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)
Este ejemplo de código es bastante bueno canónico ejemplo 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 1
y el número final será tu cuenta.
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 el next
funció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 utilizar lo que se denomina "desempaque 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 item
se refiere al primer elemento, '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)
respondido 09 mar '18, 15:03
¿El "Conseguir un recuento"ejemplo funciona cuando items
¿esta vacio? - Iceberg
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í, el Los corchetes y las comas también se generan como si fueran parte de los datos en sí.). ¿Qué va mal aquí? - user12379095
@ 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. - Aaron Hall ♦
@Bergi: No lo hará, pero puedes agregar count = 0
antes del ciclo para asegurarse de que tiene un valor (y es el correcto cuando el ciclo nunca se asigna a count
, ya que por definición no había ítems). - ShadowRanger
173
Es bastante sencillo empezar desde 1
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+
Respondido 05 Feb 21, 12:02
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, item
solo index
es muy engañoso, como ha señalado. Solo usa for index, item in enumerate(ints)
. - antti haapala
Es mejor encerrar el índice entre paréntesis como (índice), funcionará en las versiones 2 y 3 de Python - higull
@AnttiHaapala La razón, supongo, es que la salida esperada de la pregunta comienza en el índice 1 en lugar de 0 - Pushkin
@hygull: girando index
dentro (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 funcione tanto en Py2 como en Py3 es agregar from __future__ import print_function
en la parte superior de su archivo para obtener un estilo Py3 consistente print
y cambia el print
a print(index, item)
. O leíste una edición anterior de la pregunta cuando index
fue el original tuple
, no descomprimido en dos nombres, pero los paréntesis aún no cambian nada si no puede descomprimir. - ShadowRanger
97
for i in range(len(ints)):
print i, ints[i]
Respondido 06 Feb 09, 22:02
Eso probablemente debería ser xrange
para versiones anteriores a 3.0. - ben en blanco
Utilice enumerar en su lugar - Saulspatz
Para Python 2.3 anterior, use la función incorporada enumerate ya que es más Pythonic. - Januarvs
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
@adg no veo como evitar enumerate
guarda cualquier lógica; todavía tienes que seleccionar con qué objeto indexar i
, ¿No? - Chepner
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. Usando 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. Crear una variable para contener el índice (usar for
)
for index in range(len(lst)): # or xrange
# you will have to write extra code to get the element
3. Crear una variable para contener el índice (usar while
)
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. e.g. usar itertools.chain
con que. Maneja los bucles anidados mejor que los otros ejemplos.
Respondido 10 Feb 18, 20:02
32
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 bucle en 3.7 Python es usar el enumerar método para listas pequeñas, medianas y grandes.
Por favor mira diferentes aproximaciones que se puede utilizar para iterar sobre la lista y acceder al valor del índice y sus métricas de rendimiento (que supongo que sería útil 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 uso enumerate
El método 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:
Respondido el 20 de junio de 20 a las 10:06
"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. - usuario4805123
¿Qué tal actualizar la respuesta a Python 3? - Georgy
@Georgy tiene sentido, en Python 3.7 enumerate es el ganador total :) - andriy ivaneyko
31
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)
>>>
Respondido 06 Feb 09, 22:02
Es no incorrecto 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 desglosan en la fuente: + - valor naram
Alguna pitón extremistas diría, no hagas esto. Pero lo dije solo para indicar que hay más de una forma posible: valor naram
niiice, algo que los usuarios de c pueden entender - Ahmad
"Pasado de moda" no significa en realidad "incorrecto" - Charlie Martin
15
Esto es lo que obtiene cuando accede al índice en for
bucles:
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
Respondido el 20 de junio de 20 a las 10:06
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]
contestado el 26 de mayo de 15 a las 00:05
12
Según esta discusión: http://bytes.com/topic/python/answers/464012-objects-list-index
Iteración del contador de bucles
El idioma actual para recorrer los índices hace uso de la función incorporada range
función:
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 utilizando el nuevo zip
función incorporada:
for i in range(len(sequence)):
e = sequence[i]
# work with index i and element e
or
for i, e in zip(range(len(sequence)), sequence):
# work with index i and element e
contestado el 22 de mayo de 19 a las 15:05
Esto no funcionará para iterar a través de generadores. Simplemente use enumerate (). - Tadeck
Hoy en día, el idioma actual es enumerar, no la llamada de rango. - TankorSmash
y es lo mismo que la respuesta anterior: stackoverflow.com/a/522576/6451573 - Jean-François Fabre ♦
11
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
contestado el 26 de mayo de 15 a las 11:05
10
Si tuviera que iterar nums = [1, 2, 3, 4, 5]
yo 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])
contestado el 26 de mayo de 20 a las 02:05
10
La mejor solución para este problema es utilizar el enumerate
función incorporada.
enumerate
devuelve 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)
respondido 01 mar '21, 03:03
9
En tu 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, el enumerate
La funció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 a la start=n
cambiar por 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
contestado el 22 de mayo de 19 a las 16:05
6
Si no hay un valor duplicado en la lista:
for i in ints:
indx = ints.index(i)
print(i, indx)
contestado el 22 de mayo de 19 a las 16:05
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. - stam kaly
La primera opción es O (n²), una idea terrible. Si su lista tiene 1000 elementos, le llevará literalmente 1000 veces más que usar enumerate
. Deberías eliminar esta respuesta. - Boris
5
También puede intentar lo siguiente:
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']
Respondido 07 Feb 18, 14:02
3
Puede utilizar el index
Método
ints = [8, 23, 45, 12, 78]
inds = [ints.index(i) for i in ints]
EDITAR
Destacado en el comentario que este método no funciona si hay duplicados en ints
, el método siguiente 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 en ints
como una lista de tuplas.
Utiliza el método de enumerate
en la respuesta seleccionada a esta pregunta, pero con comprensión de la lista, lo que la hace más rápida con menos código.
contestado el 31 de mayo de 18 a las 07:05
3
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
Salida:
Respondido el 07 de Septiembre de 20 a las 09:09
1
Para imprimir la tupla de (índice, valor) en la comprensión de la lista usando un for
bucle:
ints = [8, 23, 45, 12, 78]
print [(i,ints[i]) for i in range(len(ints))]
Salida:
[(0, 8), (1, 23), (2, 45), (3, 12), (4, 78)]
Respondido 24 Abr '18, 11:04
0
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)
contestado el 15 de mayo de 18 a las 06:05
Esto se descompondrá si hay elementos repetidos en la lista como index()
buscará la primera aparición de x
, sin mencionar la O ( n ^ 2 ) tiempo necesario para buscar cada elemento. - Pedro Szoldan
totalmente de acuerdo en que no funcionará para elementos duplicados en la lista. Después de todo, también estoy aprendiendo Python. - Sumit Kumar
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python loops list or haz tu propia pregunta.
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 - plugwash