En este tutorial veremos qué es la función enumerate() de Python, cuándo se utiliza, qué tipo de objetos crea, su sintaxis y cómo funciona. Después, revisaremos ejemplos enumerando distintos tipos de objetos en Python, las alternativas a enumerate() y por qué suelen ser menos adecuadas para la misma tarea.
¿Qué es enumerate en Python y cuándo se usa?
enumerate() es una función incorporada de Python que recibe un iterable (una colección de elementos o cualquier objeto de Python que soporte iteración, como tuplas, listas, conjuntos o cadenas), recorre sus elementos internamente y devuelve un objeto de tipo enumerate. En otras palabras, asigna un contador que aumenta de 1 en 1 a cada elemento del iterable y nos ayuda a llevar la cuenta de las iteraciones al recorrer ese objeto. Tras crear un objeto enumerate, podemos convertirlo en una lista, una tupla o un diccionario (usando list(), tuple() o dict(), respectivamente), o bien iterar directamente sobre él para acceder tanto a los elementos como a sus índices correspondientes.
Usar enumerate() resulta útil por su eficiencia en memoria y computación frente a bucles for convencionales, ya que devuelve el índice y el elemento correspondiente de una sola vez.
Aquí, iterable es el objeto que queremos enumerar, y start es un parámetro opcional que define el índice inicial del contador (por defecto, será el índice típico basado en 0 de Python).
Ten en cuenta que aplicar enumerate() a un iterable no modifica el objeto original. En su lugar, el objeto enumerate resultante debe asignarse a una variable si queremos seguir usándolo.
Ahora, veamos cómo funciona esta función con distintos tipos de iterables de Python.
Enumerar una lista
Primero, aplicamos enumerate() a una lista de Python:
drinks =['tea','coffee','cappuccino','lemonade']
enumerated_drinks =enumerate(drinks)print(type(enumerated_drinks))print(enumerated_drinks)Con la tecnología de
El tipo del objeto resultante es enumerate y, al imprimirlo, solo confirmamos de nuevo el tipo de objeto y dónde se almacena en memoria. Probemos a acceder al primer elemento de este objeto igual que lo haríamos con una lista o tupla de Python:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)~\AppData\Local\Temp/ipykernel_5948/1233607596.py in<module>---->1print(enumerated_drinks[0])
TypeError:'enumerate'objectisnot subscriptableCon la tecnología de
Obtenemos un error que indica que no podemos acceder a los componentes de un objeto enumerate de ese modo. Para ello, debemos convertirlo en lista, tupla o diccionario, o iterar directamente sobre el objeto enumerate. Convirtámoslo en una lista:
list_enumerated_drinks =list(enumerated_drinks)print(list_enumerated_drinks)Con la tecnología de
Ahora vemos claramente la estructura interna de la lista resultante: cada elemento es una tupla de 2 componentes donde el primero es el índice del elemento correspondiente en la lista original y el segundo es el propio elemento. Podemos acceder a sus elementos con indexación normal:
print(list_enumerated_drinks[0])print(list_enumerated_drinks[0][1])Con la tecnología de
La estructura interna de la tupla anterior es idéntica a la de la lista creada antes. Sin embargo, esta vez hemos cambiado el contador para que empiece en 1, más "humano" que el índice basado en 0 de Python.
Hay un método interesante que conviene mencionar: next(). Volvamos a crear enumerated_drinks y probemos este método en acción:
enumerated_drinks =enumerate(drinks)print(next(enumerated_drinks))print(next(enumerated_drinks))print(next(enumerated_drinks))print(next(enumerated_drinks))print(next(enumerated_drinks))Con la tecnología de
Salida:
(0,'tea')(1,'coffee')(2,'cappuccino')(3,'lemonade')---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)~\AppData\Local\Temp/ipykernel_5948/330134057.py in<module>4print(next(enumerated_drinks))5print(next(enumerated_drinks))---->6print(next(enumerated_drinks))
StopIteration:Con la tecnología de
Como ves, cada vez que llamamos a este método sobre un objeto enumerate, devuelve el siguiente elemento (y comprobamos de nuevo que cada elemento es una tupla de 2 componentes con el par contador-elemento). Cuando se agotan todos los elementos, el objeto enumerate queda exhausto y volver a llamar a next() lanza un error StopIteration. De hecho, si ahora intentamos convertir ese objeto en una lista, veremos que está vacía:
Esto significa que en cada llamada a next() se «consume» un elemento del objeto enumerate; cada vez se hace más pequeño hasta agotarse por completo. Veremos esta propiedad también más adelante al usar bucles for sobre ellos.
Si quieres aprender más sobre listas de Python y otros conceptos básicos, puedes hacer el curso Introduction to Python de DataCamp.
Enumerar una tupla
Aplicar enumerate() a una tupla es idéntico a hacerlo con una lista:
drinks =('tea','coffee','cappuccino','lemonade')
enumerated_drinks =enumerate(drinks)print(enumerated_drinks)Con la tecnología de
Cada par clave:valor del diccionario resultante representa el par contador-elemento correspondiente. Podemos acceder a los valores del diccionario de la forma habitual en Python:
print(dict_enumerated_drinks[0])print(dict_enumerated_drinks[3])Con la tecnología de
list_enumerated_hello_world =list(enumerated_hello_world)print(list_enumerated_hello_world)Con la tecnología de
Salida:
[(10,'H'),(11,'e'),(12,'l'),(13,'l'),(14,'o'),(15,','),(16,' '),(17,'W'),(18,'o'),(19,'r'),(20,'l'),(21,'d'),(22,'!')]Con la tecnología de
Vemos las ya familiares tuplas de 2 elementos, donde el primero es el contador del carácter correspondiente (en este caso, empezando en 10) y el segundo es el propio carácter. El espacio en blanco y los signos de puntuación también cuentan.
Volvamos a crear enumerated_hello_world, esta vez sin start=10, y apliquemos next sobre él:
enumerated_hello_world =enumerate('Hello, World!')print(next(enumerated_hello_world))print(next(enumerated_hello_world))print(next(enumerated_hello_world))print(next(enumerated_hello_world))print(next(enumerated_hello_world))print(next(enumerated_hello_world))
# Crear una lista con lo que queda del objeto enumerateprint(list(enumerated_hello_world))Con la tecnología de
Salida:
(0,'H')(1,'e')(2,'l')(3,'l')(4,'o')(5,',')[(6,' '),(7,'W'),(8,'o'),(9,'r'),(10,'l'),(11,'d'),(12,'!')]Con la tecnología de
En la última línea dejamos de llamar a next() y convertimos enumerated_hello_world en una lista. La lista resultante contiene los caracteres que quedaban en el objeto enumerate tras varias llamadas a next().
Enumerar con un bucle for
Por último, veamos cómo funciona enumerate() junto con un bucle for:
for item inenumerate(['tea','coffee','cappuccino','lemonade']):print(item)Con la tecnología de
En cada iteración se devuelve la tupla contador-elemento, igual que ocurre al usar next(). Aunque no se aprecie en el fragmento anterior, el objeto enumerate también va perdiendo elementos (las tuplas de 2 componentes) una a una en cada iteración. Para demostrarlo, reescribamos el ejemplo y comprobemos la longitud de la lista resultante tras terminar todas las iteraciones:
drinks =['tea','coffee','cappuccino','lemonade']
enumerated_drinks =enumerate(drinks)
for item in enumerated_drinks:print(item)print(list(enumerated_drinks))Con la tecnología de
Igual que al usar next(), iterar sobre un objeto enumerate lo va agotando poco a poco.
Volvamos al ejemplo anterior. ¿Cómo accedemos a cada elemento por separado dentro de cada tupla? Para ello, añadimos una variable de iteración más y desempaquetamos las tuplas:
for count, drink inenumerate(['tea','coffee','cappuccino','lemonade']):print(count, drink)Con la tecnología de
Arriba, devolvemos dos variables por cada tupla: una para el contador y otra para el elemento.
Ten en cuenta que también podemos implementar lo mismo sin usar enumerate(). Por ejemplo, podemos introducir una variable contador fuera del bucle e incrementarla en 1 en cada iteración:
count =0for drink in['tea','coffee','cappuccino','lemonade']:print(count, drink)
count +=1Con la tecnología de
Además, en ambas alternativas a enumerate() también podemos ajustar el contador para que no empiece en cero:
count =1for drink in['tea','coffee','cappuccino','lemonade']:print(count, drink)
count +=1
print('\n')
drinks =['tea','coffee','cappuccino','lemonade']for count inrange(len(drinks)):print(count +1, drinks[count])Con la tecnología de
Salida:
1 tea
2 coffee
3 cappuccino
4 lemonade
1 tea
2 coffee
3 cappuccino
4 lemonadeCon la tecnología de
Sin embargo, comparadas con enumerate(), ambas aproximaciones son más aparatosas, propensas a errores (por ejemplo, podemos olvidarnos de actualizar el contador manualmente) y requieren más código. Por eso, usar enumerate() es la forma más pythónica siempre que necesites acceder al contador y al elemento de un iterable en cada iteración.
Conclusión
En este tutorial hemos aprendido muchas cosas sobre enumerate() en Python: para qué sirve, qué alternativas tiene y por qué suele ser más eficaz que ellas. enumerate() quizá no sea familiar para quienes empiezan con Python, e incluso programadores avanzados pueden no tener presente esta función tan útil.
Si te gustaría profundizar en enumerate(), prueba el curso Python Data Science Toolbox (Part 2), que explora iteradores e iterables en detalle y ofrece ejercicios interactivos para poner en práctica nuevas habilidades. Además, si quieres dominar otros conceptos de Python, quizá te interese Learn Python with DataCamp, que incluye varios itinerarios de aprendizaje y de carrera, chuletas, tutoriales, certificaciones en Python y pruebas de evaluación.
Descubre cómo escribir funciones en Python reutilizables y eficientes. Domina los parámetros, las sentencias return y temas avanzados como las funciones lambda. Organiza mejor tu código con main() y otras buenas prácticas.
Un tutorial introductorio completo sobre los bucles en Python. ¡Aprende y practica los bucles while y Bucle for, los bucles anidados, las palabras clave break y continue, la función range y mucho más!
En este tutorial veremos qué es la función enumerate() de Python, cuándo se utiliza, qué tipo de objetos crea, su sintaxis y cómo funciona. Después, revisaremos ejemplos enumerando distintos tipos de objetos en Python, las alternativas a enumerate() y por qué suelen ser menos adecuadas para la misma tarea.
¿Qué es enumerate en Python y cuándo se usa?
enumerate() es una función incorporada de Python que recibe un iterable (una colección de elementos o cualquier objeto de Python que soporte iteración, como tuplas, listas, conjuntos o cadenas), recorre sus elementos internamente y devuelve un objeto de tipo enumerate. En otras palabras, asigna un contador que aumenta de 1 en 1 a cada elemento del iterable y nos ayuda a llevar la cuenta de las iteraciones al recorrer ese objeto. Tras crear un objeto enumerate, podemos convertirlo en una lista, una tupla o un diccionario (usando list(), tuple() o dict(), respectivamente), o bien iterar directamente sobre él para acceder tanto a los elementos como a sus índices correspondientes.
Usar enumerate() resulta útil por su eficiencia en memoria y computación frente a bucles for convencionales, ya que devuelve el índice y el elemento correspondiente de una sola vez.
Sintaxis
La sintaxis de enumerate() es muy sencilla:
Aquí, iterable es el objeto que queremos enumerar, y start es un parámetro opcional que define el índice inicial del contador (por defecto, será el índice típico basado en 0 de Python).
Ten en cuenta que aplicar enumerate() a un iterable no modifica el objeto original. En su lugar, el objeto enumerate resultante debe asignarse a una variable si queremos seguir usándolo.
Ahora, veamos cómo funciona esta función con distintos tipos de iterables de Python.
Enumerar una lista
Primero, aplicamos enumerate() a una lista de Python:
Salida:
El tipo del objeto resultante es enumerate y, al imprimirlo, solo confirmamos de nuevo el tipo de objeto y dónde se almacena en memoria. Probemos a acceder al primer elemento de este objeto igual que lo haríamos con una lista o tupla de Python:
Salida:
Obtenemos un error que indica que no podemos acceder a los componentes de un objeto enumerate de ese modo. Para ello, debemos convertirlo en lista, tupla o diccionario, o iterar directamente sobre el objeto enumerate. Convirtámoslo en una lista:
Salida:
Ahora vemos claramente la estructura interna de la lista resultante: cada elemento es una tupla de 2 componentes donde el primero es el índice del elemento correspondiente en la lista original y el segundo es el propio elemento. Podemos acceder a sus elementos con indexación normal:
Salida:
Ahora convirtamos un objeto enumerate creado a partir de la lista original en una tupla. Además, esta vez fijaremos el parámetro opcional start a 1:
Salida:
La estructura interna de la tupla anterior es idéntica a la de la lista creada antes. Sin embargo, esta vez hemos cambiado el contador para que empiece en 1, más "humano" que el índice basado en 0 de Python.
Hay un método interesante que conviene mencionar: next(). Volvamos a crear enumerated_drinks y probemos este método en acción:
Salida:
Como ves, cada vez que llamamos a este método sobre un objeto enumerate, devuelve el siguiente elemento (y comprobamos de nuevo que cada elemento es una tupla de 2 componentes con el par contador-elemento). Cuando se agotan todos los elementos, el objeto enumerate queda exhausto y volver a llamar a next() lanza un error StopIteration. De hecho, si ahora intentamos convertir ese objeto en una lista, veremos que está vacía:
Salida:
Esto significa que en cada llamada a next() se «consume» un elemento del objeto enumerate; cada vez se hace más pequeño hasta agotarse por completo. Veremos esta propiedad también más adelante al usar bucles for sobre ellos.
Si quieres aprender más sobre listas de Python y otros conceptos básicos, puedes hacer el curso Introduction to Python de DataCamp.
Enumerar una tupla
Aplicar enumerate() a una tupla es idéntico a hacerlo con una lista:
Salida:
De nuevo, obtenemos un objeto enumerate cuyos elementos no son accesibles con la indexación habitual. Transformémoslo esta vez en un diccionario:
Salida:
Cada par clave:valor del diccionario resultante representa el par contador-elemento correspondiente. Podemos acceder a los valores del diccionario de la forma habitual en Python:
Salida:
Si quieres profundizar en diccionarios de Python y pandas, echa un vistazo al curso Intermediate Python.
Enumerar una cadena
Como las cadenas de Python son secuencias de caracteres y por tanto objetos iterables, también podemos crear un enumerate de una cadena:
Salida:
Como antes, convirtamos este objeto en una lista:
Salida:
Vemos las ya familiares tuplas de 2 elementos, donde el primero es el contador del carácter correspondiente (en este caso, empezando en 10) y el segundo es el propio carácter. El espacio en blanco y los signos de puntuación también cuentan.
Volvamos a crear enumerated_hello_world, esta vez sin start=10, y apliquemos next sobre él:
Salida:
En la última línea dejamos de llamar a next() y convertimos enumerated_hello_world en una lista. La lista resultante contiene los caracteres que quedaban en el objeto enumerate tras varias llamadas a next().
Enumerar con un bucle for
Por último, veamos cómo funciona enumerate() junto con un bucle for:
Salida:
En cada iteración se devuelve la tupla contador-elemento, igual que ocurre al usar next(). Aunque no se aprecie en el fragmento anterior, el objeto enumerate también va perdiendo elementos (las tuplas de 2 componentes) una a una en cada iteración. Para demostrarlo, reescribamos el ejemplo y comprobemos la longitud de la lista resultante tras terminar todas las iteraciones:
Salida:
Igual que al usar next(), iterar sobre un objeto enumerate lo va agotando poco a poco.
Volvamos al ejemplo anterior. ¿Cómo accedemos a cada elemento por separado dentro de cada tupla? Para ello, añadimos una variable de iteración más y desempaquetamos las tuplas:
Salida:
Arriba, devolvemos dos variables por cada tupla: una para el contador y otra para el elemento.
Ten en cuenta que también podemos implementar lo mismo sin usar enumerate(). Por ejemplo, podemos introducir una variable contador fuera del bucle e incrementarla en 1 en cada iteración:
Salida:
Como alternativa, podemos usar la combinación de range() y len() sobre una lista (o tupla, cadena, etc.) predefinida:
Salida:
Además, en ambas alternativas a enumerate() también podemos ajustar el contador para que no empiece en cero:
Salida:
Sin embargo, comparadas con enumerate(), ambas aproximaciones son más aparatosas, propensas a errores (por ejemplo, podemos olvidarnos de actualizar el contador manualmente) y requieren más código. Por eso, usar enumerate() es la forma más pythónica siempre que necesites acceder al contador y al elemento de un iterable en cada iteración.
Conclusión
En este tutorial hemos aprendido muchas cosas sobre enumerate() en Python: para qué sirve, qué alternativas tiene y por qué suele ser más eficaz que ellas. enumerate() quizá no sea familiar para quienes empiezan con Python, e incluso programadores avanzados pueden no tener presente esta función tan útil.
Si te gustaría profundizar en enumerate(), prueba el curso Python Data Science Toolbox (Part 2), que explora iteradores e iterables en detalle y ofrece ejercicios interactivos para poner en práctica nuevas habilidades. Además, si quieres dominar otros conceptos de Python, quizá te interese Learn Python with DataCamp, que incluye varios itinerarios de aprendizaje y de carrera, chuletas, tutoriales, certificaciones en Python y pruebas de evaluación.