IWI131 Programación


Listas Bi-dimensionales (listas de listas)



Departamento de Informática
Universidad Técnica Federico Santa María

Listas Bi-dimensionales: Definición

Las listas bi-dimensionales se caracterizan por que al menos un elemento de la lista es, a su vez, otra lista.

Tambien se les llama: listas de listas o listas anidadas.

Las listas de listas tienen las mismas caractersiticas que una lista normal (o uni-dimensional). Es decir:

  • Se les puede aplicar los métodos ya vistos: .append(), .sort(), .remove(), etc.
  • Estas listas pueden tener cualquier tamaño, incluso pueden crearse como listas vacias.
  • Pueden contener cualquier tipo de dato.

Ejemplo de listas de listas pueden ser:

In [1]:
L1 = [1,2,3, [4,5,6,7,8], 9]
L2 = [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
L3 = [[],[]]
print('Lista L1:', L1)
print('Lista L2:', L2)
print('Lista L3:', L3)
Lista L1: [1, 2, 3, [4, 5, 6, 7, 8], 9]
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
Lista L3: [[], []]

Se debe tener conciencia que en estos casos, los elementos de las listas pueden ser elemetnos que pueden contener a su vez otros elementos.

Ejemplo Los elementos de la lista L1 son 5: 1, 2, 3, [4,5,6,7,8] y 9. Entonces, el cuarto elemento, es decir el elemento con el indice 3, es: [4,5,6,7,8]

In [2]:
print(L1[3])
[4, 5, 6, 7, 8]
In [3]:
print(L1[-1])
9

Entonces, teniendo las listas L1, L2, y L3

In [4]:
print('Lista L1:', L1)
print('Lista L2:', L2)
print('Lista L3:', L3)
Lista L1: [1, 2, 3, [4, 5, 6, 7, 8], 9]
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
Lista L3: [[], []]

¿Qué nos entrega las siguientes instrucciones?

In [5]:
v1 = L2[0]
v2 = L2[-1]
v3 = L3[1]
v4 = L1[3:]
v5 = L1[:3]
v6 = L2[2:3]
In [6]:
print(v1)
print(v2)
print(v3)
print(v4)
print(v5)
print(v6)
True
[False, '789']
[]
[[4, 5, 6, 7, 8], 9]
[1, 2, 3]
[[1988, 4, 12]]

Listas Bi-dimensionales: manejo de indices

El manejo de indices en listas de listas aumenta un poco su complejidad, pero es importante entenderlo ya que es posible obtener cualquier valor y esto facilita mucho el trabajo.

Hasta ahora sabemos que para obtener el valor de un elemento de una lista es necesario usar los paréntesis cuadrados o corchetes [ ]

Este operador (operador rebanador) nos permite acceder a elementos de un iterable, es decir: lista y string.

Entonces, podemos usar tantas veces como queramos el operador rebanador, siempre y cuando tengamos al lado izquierda una lista o string.

Volvamos al ejemplo anterior, es decir, con las listas L1, L2, y L3

In [7]:
print('Lista L1:', L1)
print('Lista L2:', L2)
print('Lista L3:', L3)
Lista L1: [1, 2, 3, [4, 5, 6, 7, 8], 9]
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
Lista L3: [[], []]

Si sabemos que: L1[3] es la lista [4,5,6,7,8], entonces podemos obtener el primer elemento de la siguiente manera:

In [8]:
sub_lista = L1[3]
primer_elem = sub_lista[0]
print('El primer elemento de la sublista es:',primer_elem)
El primer elemento de la sublista es: 4

De una manera abreviada, y más conveniente, podemos escribir lo mismo de la siguiente manera:

In [9]:
primer_elem = L1[3][0]
print('El primer elemento de la sublista es:',primer_elem)
El primer elemento de la sublista es: 4

Los paréntesis corchetes: [ ], permiten acceder a la ubicación que le damos con el valor entero (positivo o negativo), pero además, es posible realizar esto tantas veces como queramos siempre y cuando lo que este a lado izquierda sea una lista o un string.

Otro ejemplo: vamos a acceder a la palabra "de" del string "listas de listas" de la lista L2.

In [10]:
print('Lista L2:', L2)
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
In [11]:
string_completo = L2[3]
palabra_de = string_completo[6:8]
print(palabra_de)
de

De manera abreviada, y más conveniente seria:

In [12]:
print(L2[3][6:8])
de

Entonces, ¿qué nos entrega las siguientes instrucciones?

In [13]:
print('Lista L1:', L1)
print('Lista L2:', L2)
print('Lista L3:', L3)
Lista L1: [1, 2, 3, [4, 5, 6, 7, 8], 9]
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
Lista L3: [[], []]
In [14]:
x1 = L1[3][-1]
x2 = L2[-1][0]
x3 = L2[3][9:]
In [15]:
print(x1)
print(x2)
print(x3)
8
False
listas

¿Y si generalizamos incluyendo más paréntesis corchetes?

In [16]:
z1 = L1[3:][0][1]
z2 = L2[:][-1][-1][-1]
z3 = L2[::-1][1][::-1]
In [17]:
print(z1)
print(z2)
print(z3)
5
9
satsil ed atsil

Listas Bi-dimensioanles: recorrerlas mediante for

La forma de recorrer las listas mediante for es muy sencilla. Se debe seguir las mismas reglas que para recorrer una lista uni-dimensional.

Se debe poner atención que valores toma ahora la variable que se crea en el for.

Veamos un ejemplo:

In [18]:
print('Lista L2:', L2)
Lista L2: [True, 234, [1988, 4, 12], 'lista de listas', [False, '789']]
In [19]:
for elemento in L2:
    print('Valor de la variable elemento:', elemento)
Valor de la variable elemento: True
Valor de la variable elemento: 234
Valor de la variable elemento: [1988, 4, 12]
Valor de la variable elemento: lista de listas
Valor de la variable elemento: [False, '789']

Veamos otro ejemplo:

In [20]:
ramos = [['Progra','IWI-131', 3],
         ['Mate', 'MAT-021', 5],
         ['Fisica', 'FIS-100', 3],
         ['Ed.Fisica', 'DEW-100', 1],
         ['Inmanente', 'HRW-102', 2],
        ]

for nombre, sigla, c in ramos: # 3 variables en vez de 1
    print(nombre, 'tiene', c, 'creditos')
Progra tiene 3 creditos
Mate tiene 5 creditos
Fisica tiene 3 creditos
Ed.Fisica tiene 1 creditos
Inmanente tiene 2 creditos

En la línea del for ahora hay 3 variables en vez de 1. Esto es posible ya que sabemos que cada elemento de la lista ramos, siempre, tendrá 3 elementos.

La lista ramos es una lista de listas, donde cada sub-lista siempre tiene 3 elementos.

Cada variable creada en la linea del for, tomará cada valor de las sub-listas. Esto será en orden, es decir: primera variable con el primer elemento de la sub-lista, y así sucesivamente.

Siguiendo el ejemplo anterior, es posible recorrer cada sub-lista para así obtener cada elemento uno por uno sin que falte ninguno. Esto se hace con un for adicional:

In [21]:
ramos = [['Progra','IWI-131', 3],
         ['Mate', 'MAT-021', 5],
         ['Fisica', 'FIS-100', 3],
         ['Ed.Fisica', 'DEW-100', 1],
         ['Inmanente', 'HRW-102', 2],
        ]

for asignatura in ramos:
    print('Valor de la variable asignatura:', asignatura)
    for dato in asignatura:
        print('Valor de la variable dato:', dato)
Valor de la variable asignatura: ['Progra', 'IWI-131', 3]
Valor de la variable dato: Progra
Valor de la variable dato: IWI-131
Valor de la variable dato: 3
Valor de la variable asignatura: ['Mate', 'MAT-021', 5]
Valor de la variable dato: Mate
Valor de la variable dato: MAT-021
Valor de la variable dato: 5
Valor de la variable asignatura: ['Fisica', 'FIS-100', 3]
Valor de la variable dato: Fisica
Valor de la variable dato: FIS-100
Valor de la variable dato: 3
Valor de la variable asignatura: ['Ed.Fisica', 'DEW-100', 1]
Valor de la variable dato: Ed.Fisica
Valor de la variable dato: DEW-100
Valor de la variable dato: 1
Valor de la variable asignatura: ['Inmanente', 'HRW-102', 2]
Valor de la variable dato: Inmanente
Valor de la variable dato: HRW-102
Valor de la variable dato: 2

Listas N-dimensionales o listas de listas de listas de listas ... de listas

Como hemos visto, podemos imaginar, y nada nos prohibe, crear listas n-dimensionales. Esto quiere decir que podemos tener varias "listas anidadas" dentro de una gran lista. Veamos un ejemplo:

In [22]:
L = [[1,2,3,4,[11,22,33]],[5,6,7,[66]],[[88,99],8,9, [88,99,[888,[8888,9999]]]]]
print(L)
[[1, 2, 3, 4, [11, 22, 33]], [5, 6, 7, [66]], [[88, 99], 8, 9, [88, 99, [888, [8888, 9999]]]]]
In [23]:
a1 = L[0]
a2 = L[2][3][0]
a3 = L[1][-1]
a4 = L[-1][-1][-1][1][0]
In [24]:
print(a1)
print(a2)
print(a3)
print(a4)
[1, 2, 3, 4, [11, 22, 33]]
88
[66]
8888

Cada paréntesis corchete nos permite adentrarnos más a la lista. Recuerdar que esto es posible si el elemento de la lista es un iterable: string o lista

Ejercicios

1.- Dada las siguientes listas, diga que entrega las expresiones:

In [25]:
a = [5, 1, 4, 9, 0]
b = list(range(3, 10)) + list(range(20, 23))
c = [[1, 2], [3, 4, 5], [6, 7]]
d = ['perro', 'gato', 'jirafa', 'elefante']
e = ['a', a, 2 * a]
In [26]:
a[2]
b[9]
c[1][2]
e[0] == e[1]
len(c)
len(c[0])
len(e)
c[-1]
c[-1][+1]
c[2:] + d[2:]
a[3:10]
a[3:10:2]
d.index('jirafa')
e[c[0][1]].count(5)
a.sort()
a[2]
print('fin')
fin

2. Usted desea ir al cine a ver la próxima película del estudio Marvel lo antes posible para evitar los molestos spoilers. Para ello la página del cine le muestra la lista sala con la disponibilidad de asientos. La sala del cine siempre será representada por una lista con n listas, cada una de ellas con n strings. Cada string puede tener los valores O que indica que el asiento está disponible o X que indica que está ocupado. El siguiente es un ejemplo para n igual a 5. Nota: el valor de n no debería ser importante.

sala = [
["X","X","X","O","O"],
["X","X","X","X","O"],
["X","O","X","O","X"],
["X","X","X","X","O"],
["O","O","X","O","O"],
]
In [27]:
sala = [
["X","X","X","O","O"],
["X","X","X","X","O"],
["X","O","X","O","X"],
["X","X","X","X","O"],
["O","O","X","O","O"],
]

sala2 = [
["X","X","X"],
["X","X","X"],
["X","X","X"],
["X","X","X"]
]

Escriba la función asientos_disponibles(sala) que indique si la sala del cine tiene asientos disponibles. La función debe retornar True si la sala tiene asientos disponibles y False en caso contrario.

>>> asientos_disponibles(sala)
True
In [28]:
def asientos_disponibles(sala):
    for fila in sala:
        for asiento in fila:
            if asiento == 'O':
                return True #encontramos algun asiento disponible
    return False #nunca encontramos un asiento disponible
In [29]:
asientos_disponibles(sala)
Out[29]:
True
In [30]:
asientos_disponibles(sala2)
Out[30]:
False

Escriba la función disponible(fila,columna,sala) que reciba una sala del cine. La función debe retornar True si el asiento de la fila y columna ingresados está disponible y False en caso contrario. Si ingresa una fila o columna que no existan también deberá retornar False.

>>> disponible(2, 4, sala)
False
>>> disponible(10, 4, sala)
False
>>> disponible(0, 3, sala)
True
In [31]:
def disponible(fila, columna, sala):
    if -len(sala) <= fila < len(sala):# que significa esta condicion
        if -len(sala[fila]) < columna < len(sala[fila]): #que significa esta condicion
            return sala[fila][columna] == "O"
        else:
            return False
    else:
        return False
In [32]:
disponible(2, 4, sala)
Out[32]:
False
In [33]:
disponible(10, 4, sala)
Out[33]:
False
In [34]:
disponible(0, 3, sala)
Out[34]:
True

Escriba la función porcentaje_disponible(sala) que indique porcentualmente la disponibilidad de una sala de cine.

>>> porcentaje_disponible(sala)
0.2
In [35]:
def porcentaje_disponible(sala):
    cantidad_asientos = 0
    cantidad_disponible = 0
    for fila in sala:
        for asiento in fila:
            if asiento == 'O':
                cantidad_disponible+=1
            cantidad_asientos+=1
    return round(cantidad_disponible/cantidad_asientos,1)
In [36]:
porcentaje_disponible(sala)
Out[36]:
0.4
In [37]:
porcentaje_disponible(sala2)
Out[37]:
0.0

Usted desea ir con sus m amigos a ver la película y todos quieren ir a ver la película en la misma sala de cine. Debid al grán éxito en la pre-venta es posible que no queden muchos asientos. Escriba la función hay_espacio_suficiente(m,sala) que reciba un entero m con la cantidad de amigos (usted incluido) que quieren ir a ver la película y la sala del cine. La función debe retornar True si hay espacio suficiente para que todos puedan ver la película en la sala de cine o False en caso contrario :(

>>> hay_espacio_suficiente(12, sala)
False
>>> hay_espacio_suficiente(3, sala)
True
In [38]:
def hay_espacio_suficiente(m,sala):
    cantidad_disponible = 0
    for fila in sala:
        for asiento in fila:
            if asiento == 'O':
                cantidad_disponible+=1
    if m <= cantidad_disponible:
        return True
    else:
        return False
In [39]:
hay_espacio_suficiente(12,sala)
Out[39]:
False
In [40]:
hay_espacio_suficiente(3,sala)
Out[40]:
True
In [41]:
hay_espacio_suficiente(5,sala)
Out[41]:
True
In [ ]: