Apéndice N — Recorriendo las estructuras de datos.

Objetivo. Describir como recorrer las secuencias (str, list, tuple, set, dict) de una forma óptima.

N.1 Iterables

  • En Python existen objetos que contienen secuencias de otros objetos.
  • Estos objetos pueden ser cadenas, listas, tuplas, diccionarios, conjuntos, archivos, entre otros.
  • Estos objetos se pueden recorrer usando ciclos for .
  • A estos objetos se les conoce también como iterables (objetos iterables, secuencias iterables, contenedores iterables, conjunto iterable).
Ejemplo N.1: Creación de estructuras de datos.
  • Crear una cadena, una lista, una tupla, un diccionario, un conjunto y leer el archivo mi_archivo.txt.
  • Posteriormente recorrer cada uno de estos iterables usando un ciclo for:
  • Creamos los iterables.
mi_cadena = "str: pythonico"
mi_lista = ['list: ', 'p','y','t','h','o','n','i','c','o']
mi_tupla = ('tuple: ', 'p','y','t','h','o','n','i','c','o')
mi_dict = {'p':1,'y':2,'t':3,'h':4,'o':5,'n':6,'i':7,'c':8,'o':9}
mi_conj = {'p','y','t','h','o','n','i','c','o'}
  • Recorremos la cadena e imprimimos cada elemento.
for c in mi_cadena:
    print(c, end='')
str: pythonico
  • Recorremos la lista e imprimimos cada elemento.
for e in mi_lista:
    print(e, end='')
list: pythonico
  • Recorremos la tupla e imprimimos cada elemento.
for e in mi_tupla:
    print(e, end='')
tuple: pythonico
  • Recorremos el diccionario e imprimimos cada elemento.
for i in mi_dict.items():
    print(i)
('p', 1)
('y', 2)
('t', 3)
('h', 4)
('o', 9)
('n', 6)
('i', 7)
('c', 8)

Observa que en este caso solo aparece una vez el elemento con clave o. Su valor es el que se le asignó por última vez, en este caso 9.

  • Recorremos el diccionario por claves.
for key in mi_dict.keys():
    print(key, end='')
pythonic
  • Recorremos el diccionario por valores.
for v in mi_dict.values():
    print(v, end=' ')
1 2 3 4 9 6 7 8 
  • Recorremos el conjunto.
for s in mi_conj:
    print(s, end = ' ')
c i h o t n y p 

Observa que le conjunto no contiene elementos repetidos.

  • Recorremos el archivo. El archivo mi_archivo.txt contiene las siguientes tres líneas:
Hola mundo
Pythonico
Primermundista
mi_archivo = open("mi_archivo.txt") # Se abre un archivo
for line in mi_archivo:
    print(line, end = '')
mi_archivo.close() # Se cierra el archivo.
Hola mundo
Pythonico
Primermundista

Lo anterior se puede hacer de forma más segura usando un gestor de contexto:

with open("mi_archivo.txt") as mi_archivo:
    for line in mi_archivo:
        print(line, end = '')
Hola mundo
Pythonico
Primermundista

N.2 Recorriendo secuencias de una forma típica.

Considera las siguientes dos listas de la misma longitud.

gatos = ['Persa', 'Sphynx', 'Ragdoll','Siamés']
origen = ['Irán', 'Toronto', 'California', 'Tailandia']
print(gatos)
print(origen)
['Persa', 'Sphynx', 'Ragdoll', 'Siamés']
['Irán', 'Toronto', 'California', 'Tailandia']

Dado que en las listas se puede usar el indexado para acceder a los elementos, podemos recorrer la lista como sigue:

N = len(gatos) # Longitud de la lista gatos

for i in range(0, N):
    print(i, gatos[i], origen[i])
0 Persa Irán
1 Sphynx Toronto
2 Ragdoll California
3 Siamés Tailandia

La anterior es una manera típica en cómo se recorren arreglos en otros lenguajes de programación. Python ofrece otras maneras que se muestran a continuación.

N.3 Función zip

La función zip(s1, s2, ...) permite combinar dos o más secuencias en una sola, genera tuplas con los elementos de las secuencias.

# Combinamos las listas en una sola secuencia
print('\n(Raza, Origen)\n'+'-'*20)
for t in zip(gatos, origen):
    print(t)

(Raza, Origen)
--------------------
('Persa', 'Irán')
('Sphynx', 'Toronto')
('Ragdoll', 'California')
('Siamés', 'Tailandia')
# Se puede extraer la información de cada secuencia:
for g, o in zip(gatos, origen):
    print('La raza {} proviene de {}'.format(g, o))
La raza Persa proviene de Irán
La raza Sphynx proviene de Toronto
La raza Ragdoll proviene de California
La raza Siamés proviene de Tailandia

N.4 Conversión de zip a list, tuple, set, dict

Estrictamente zip es una clase que define un tipo dentro de Python, por lo que es posible convertir del tipo zip a alguna otra secuencia básica de datos de Python.

z = zip(gatos, origen)

# Verificar el tipo de zip
print(z, type(z))
<zip object at 0x0000020183D44D00> <class 'zip'>
lista = list(zip(gatos, origen))
tupla = tuple(zip(gatos, origen))
conj = set(zip(gatos, origen))
dicc = dict(zip(gatos, origen)) # Solo funciona con dos secuencias

print(lista)
print(tupla)
print(conj)
print(dicc)
[('Persa', 'Irán'), ('Sphynx', 'Toronto'), ('Ragdoll', 'California'), ('Siamés', 'Tailandia')]
(('Persa', 'Irán'), ('Sphynx', 'Toronto'), ('Ragdoll', 'California'), ('Siamés', 'Tailandia'))
{('Sphynx', 'Toronto'), ('Ragdoll', 'California'), ('Persa', 'Irán'), ('Siamés', 'Tailandia')}
{'Persa': 'Irán', 'Sphynx': 'Toronto', 'Ragdoll': 'California', 'Siamés': 'Tailandia'}

N.5 Función enumerate

Permite enumerar los elementos de una secuencia. Genera tuplas con el número del elemento y el elemento de la secuencia.

Por ejemplo:

print(gatos)

# Enumeramos la secuencia
print('\n(Numero, Raza)\n'+'-'*20)
for t in enumerate(gatos):
    print(t)
['Persa', 'Sphynx', 'Ragdoll', 'Siamés']

(Numero, Raza)
--------------------
(0, 'Persa')
(1, 'Sphynx')
(2, 'Ragdoll')
(3, 'Siamés')
for i, g in enumerate(gatos):
    print(i, g)
0 Persa
1 Sphynx
2 Ragdoll
3 Siamés

Lo anterior permite usar el indexado para acceder a los elementos de una secuencia:

for i, g in enumerate(gatos):
    print(i, gatos[i])
0 Persa
1 Sphynx
2 Ragdoll
3 Siamés

N.6 Conversión de enumerate a list, tuple, set, dict

Estrictamente enumerate es una clase que define un tipo dentro de Python, por lo que es posible convertir del tipo enumerate a alguna otra secuencia básica de datos de Python:

e = enumerate(gatos)

# Verificar el tipo de enumerate
print(e, type(e))
<enumerate object at 0x0000020183CF7C90> <class 'enumerate'>
lista = list(enumerate(gatos))
tupla = tuple(enumerate(gatos))
conj = set(enumerate(gatos))
dicc = dict(enumerate(gatos))

print(lista)
print(tupla)
print(conj)
print(dicc)
[(0, 'Persa'), (1, 'Sphynx'), (2, 'Ragdoll'), (3, 'Siamés')]
((0, 'Persa'), (1, 'Sphynx'), (2, 'Ragdoll'), (3, 'Siamés'))
{(1, 'Sphynx'), (2, 'Ragdoll'), (3, 'Siamés'), (0, 'Persa')}
{0: 'Persa', 1: 'Sphynx', 2: 'Ragdoll', 3: 'Siamés'}

N.7 Conversión de range a list, tuple, set

Estrictamente range es una clase que define un tipo dentro de Python, por lo que es posible convertir del tipo range a alguna otra secuencia básica de datos de Python:

N = len(gatos) # Longitud de la lista gatos
r = range(0,N)

# Verificar el tipo de range
print(r, type(r))
range(0, 4) <class 'range'>
lista = list(range(0,N))
tupla = tuple(range(0,N))
conj = set(range(0,N))

print(lista)
print(tupla)
print(conj)
[0, 1, 2, 3]
(0, 1, 2, 3)
{0, 1, 2, 3}