¿Qué hace for row_number, row in enumerate(cursor):
en Python?
¿Qué enumerate
significa en este contexto?
¿Qué hace for row_number, row in enumerate(cursor):
en Python?
¿Qué enumerate
significa en este contexto?
Respuestas:
La enumerate()
función agrega un contador a un iterable.
Entonces, para cada elemento en cursor
, se produce una tupla con (counter, element)
; el for
bucle une eso a row_number
y row
, respectivamente.
Manifestación:
>>> elements = ('foo', 'bar', 'baz')
>>> for elem in elements:
... print elem
...
foo
bar
baz
>>> for count, elem in enumerate(elements):
... print count, elem
...
0 foo
1 bar
2 baz
Por defecto, enumerate()
comienza a contar en, 0
pero si le das un segundo argumento entero, comenzará desde ese número:
>>> for count, elem in enumerate(elements, 42):
... print count, elem
...
42 foo
43 bar
44 baz
Si tuviera que volver a implementar enumerate()
en Python, aquí hay dos formas de lograrlo; uno usa itertools.count()
para hacer el conteo, el otro cuenta manualmente en una función de generador :
from itertools import count
def enumerate(it, start=0):
# return an iterator that adds a counter to each element of it
return zip(count(start), it)
y
def enumerate(it, start=0):
count = start
for elem in it:
yield (count, elem)
count += 1
La implementación real en C está más cerca de la última, con optimizaciones para reutilizar un único objeto de tupla para el for i, ...
caso de desempaquetado común y usar un valor entero C estándar para el contador hasta que el contador se vuelva demasiado grande para evitar usar un objeto entero Python (que es ilimitado).
Es una función integrada que devuelve un objeto que se puede iterar. Ver la documentación .
En resumen, recorre los elementos de un iterable (como una lista), así como un número de índice, combinado en una tupla:
for item in enumerate(["a", "b", "c"]):
print item
huellas dactilares
(0, "a")
(1, "b")
(2, "c")
Es útil si desea recorrer una secuencia (u otra cosa iterable), y también desea tener un contador de índice disponible. Si desea que el contador comience desde algún otro valor (generalmente 1), puede darle eso como segundo argumento enumerate
.
item
entonces puede eliminar el paréntesis: D
yield
/ yield from
o expresiones generadoras, que implícitamente yield
); enumerate
No es un generador. Para todos los propósitos relacionados con la escritura de patos, no hay diferencia, pero la verificación explícita de tipos y los documentos del lenguaje Python solo usan el término "generador" para un propósito, que no cubre enumerate
.
Estoy leyendo un libro ( Effective Python ) de Brett Slatkin y muestra otra forma de iterar sobre una lista y también conoce el índice del elemento actual en la lista, pero sugiere que es mejor no usarlo y usarlo enumerate
. Sé que preguntaste qué significa enumerar, pero cuando entendí lo siguiente, también entendí cómo enumerate
hace que iterar sobre una lista conozca el índice del elemento actual más fácil (y más legible).
list_of_letters = ['a', 'b', 'c']
for i in range(len(list_of_letters)):
letter = list_of_letters[i]
print (i, letter)
El resultado es:
0 a
1 b
2 c
También solía hacer algo, incluso más tonto antes de leer sobre la enumerate
función.
i = 0
for n in list_of_letters:
print (i, n)
i += 1
Produce la misma salida.
Pero con enumerate
solo tengo que escribir:
list_of_letters = ['a', 'b', 'c']
for i, letter in enumerate(list_of_letters):
print (i, letter)
Como han mencionado otros usuarios, enumerate
es un generador que agrega un índice incremental al lado de cada elemento de un iterable.
Así que si usted tiene algo que decir la lista l = ["test_1", "test_2", "test_3"]
, el list(enumerate(l))
te dará algo como esto: [(0, 'test_1'), (1, 'test_2'), (2, 'test_3')]
.
Ahora, cuando esto es útil? Un posible caso de uso es cuando desea iterar sobre elementos y desea omitir un elemento específico que solo conoce su índice en la lista pero no su valor (porque su valor no se conoce en ese momento).
for index, value in enumerate(joint_values):
if index == 3:
continue
# Do something with the other `value`
Por lo tanto, su código se lee mejor porque también podría hacer un ciclo for regular range
pero luego acceder a los elementos que necesita para indexarlos (es decir, joint_values[i]
)
Aunque otro usuario mencionó una implementación del enumerate
uso zip
, creo que una forma más pura (pero un poco más compleja) sin usar itertools
es la siguiente:
def enumerate(l, start=0):
return zip(range(start, len(l) + start), l)
Ejemplo:
l = ["test_1", "test_2", "test_3"]
enumerate(l)
enumerate(l, 10)
Salida:
[(0, 'prueba_1'), (1, 'prueba_2'), (2, 'prueba_3')]
[(10, 'prueba_1'), (11, 'prueba_2'), (12, 'prueba_3')]
Como se menciona en los comentarios, este enfoque con rango no funcionará con iterables arbitrarios como lo hace la enumerate
función original .
itertools
es que surange
enfoque solo funciona con contenedores. enumerate
trabaja con iterables arbitrarios; si desea iterar un archivo, for lineno, line in enumerate(myfile):
funciona, pero no pudo hacerlo range(len(myfile))
porque la longitud no se conoce hasta que alcanza EOF.
La función enumerar funciona de la siguiente manera:
doc = """I like movie. But I don't like the cast. The story is very nice"""
doc1 = doc.split('.')
for i in enumerate(doc1):
print(i)
La salida es
(0, 'I like movie')
(1, " But I don't like the cast")
(2, ' The story is very nice')