Más sobre listas
Contents
Más sobre listas#
Important
¿Qué debemos recordar?
Sobre listas debemos tener claro lo siguiente:
Sub-listas#
Hay oportunidades en las que nuestra necesidad sea extraer una sub-lista de la lista que tenemos, por ejemplo, de la lista l = [0, 1, 2, 3, 4, 5]
requerimos los elementos desde el índice 2 hasta el 4 de nuestra lista, o los primeros \(3\) elementos o los últimos \(4\), estas tres sub-listas se obtienen así:
l = [0, 1, 2, 3, 4, 5]
subl = l[2:5]
subl
[2, 3, 4]
primeros = l[:3]
primeros
[0, 1, 2]
ultimos = l[2:]
#para mayor facilidad, podemos emplear los índices negativos
#ultimos = l[-4:]
ultimos
[2, 3, 4, 5]
Es decir, para extraer una sub-lista basta con hacerlo de la siguiente manera:
lista[índice_inicial:índice_final]
Si el ínidice inicial se omite, la lista se considerará desde el primer elemento, de manera análoga ocurre con el índice final, si se omite la sub-lista llegará hasta el último elemento de la lista original.
Los valores negativos se emplean cuando se desea hablar de los últimos elementos de una lista, con el fin de evitar confusiones.
Ejercicio:#
Extraiga tres sub-listas de una lista cuyos valores coinciden con el valor del índice, en ellas deberán estar:
Los primeros 20 elementos.
Los elementos desde le índice 100 hasta el índice 200.
Los últimos 30 elementos.
Calcule el promedio de cada una de éstas listas.
Eliminando entradas de una lista#
En otras ocasiones es muy necesario eliminar elementos de las listas, por ejemplo, vamos a eliminar el tercer elemento de la lista M = [0, 1, 2, 3, 'cuatro', 1, 1, 5.1, id(l)]
M = [0, 1, 2, 3, 'cuatro', 1, 1, 5.1, id(l)]
del M[2]
M
[0, 1, 3, 'cuatro', 1, 1, 5.1, 140420558589056]
Es decir, al seguir la línea de comando
del lista[índice_que_se_desea_eliminar]
se borra la entrada de la lista.
Listas por Comprensión:#
Las listas se pueden crear de una manera un poco más avanzada, empleando la característica que las define, si la hay. Si por ejemplo, deseamos crear la lista de los primeros \(5\) números pares podemos emplear el siguiente código:
pares = [2*i for i in range(5)]
pares
[0, 2, 4, 6, 8]
La línea anterior es equivalente al siguiente bloque:
pares = []
for i in range(5):
pares.append(2*i)
pares
[0, 2, 4, 6, 8]
De momento, podemos decir que las listas por comprensión se crean de la siguiente manera:
[expresión_que_depende_de_i for i in lista_en_la_que_varía_i]
Pero en ocasiones, es necesario introducir alguna condición ya que no requerimos de todos los valores de la lista. Por ejemplo, si en la lista anterior deseamos omitir los múltiplos de \(3\), la siguiente línea nos sería útil:
pares2 = [2*i for i in range(5) if i%3!=0]
pares2
[2, 4, 8]
Esta simple línea equivale a redactar el siguiente bloque:
pares2 = []
for i in range(5):
if i%3!=0:
pares2.append(2*i)
pares2
[2, 4, 8]
Como podemos observar, las listas por comprensión nos facilitan la escritura de listas, pero debemos tener muy claras la expresión que tienen en común todos los elementos de ella y las posibles condiciones para poder agregarlos o no. De manera general las listas por comprensión se escribren así:
[expresión_que_depende_de_i for i in lista_en_la_que_varía_i if condiciones]
Ejercicio:#
Crea una lista por comprensión cuya lista que recorre sea una cadena de caracteres arbitraria, y almacene las consonantes únicamente.
Además de las condiciones anteriores, podemos crear listas por comprensión con ciclos anidados, como por ejemplo:
nombres1 = ['Luis' ,'Pedro' ,'Michele', 'Albert', 'María José']
nombres2 = ['Luisa', 'María José' ,'Michele', 'Ana', 'Jenny']
comunes = [a for a in nombres1 for b in nombres2 if a == b]
comunes
['Michele', 'María José']
De manera general, las listas por comprensión se pueden crear de la siguiente manera:
[expresión for a in lista_para_a (opcional if condición_para_a)
for b in lista_para_b (opcional if condición_para_b)
for c in lista_para_c (opcional if condición_para_c)
...]
Ejercicio:#
Crea dos listas de números enteros y haga una lista por comprensión en la que se almacenen los productos de los números en ellas que no sean pares.
Tuplas#
Las tuplas, a diferencia de las listas, son objetos inmutables en los cuales se almacenan datos, bien sean del mismo o de diferentes tipos, siendo éste último el uso más frecuente.
De modo que definiremos nuestra primera tupa:
temperatura = 'Enero', '01', 19
#Equivalentemente
#t = ('Enero', '01', 19)
temperatura
('Enero', '01', 19)
Sin importar como la definamos: siempre se visualizarán sus elementos entre paréntesis y separados por una coma.
Para conocer la cantidad de elementos que hay en una tupla, empleamos la misma función que para las listas, la función
len(tupla)
así:
len(temperatura)
3
Si deseamos definir una tupla con un único elemento, debemos hacerlo de la siguiente manera:
tupla1elemento = 23, #Observa la coma
tupla1elemento
(23,)
La coma es la que indica que es una tupla, ya que se si hace sin ella, incluso entre paréntesis, se guardará el entero 23 y no la tupla cuyo único elemento es el 23.
Para acceder a la información almacenada en las diferentes entradas de una tupla, lo hacemos de la misma manera que lo hicimos con las listas, es decir, tupla[índice]
, así:
temperatura[0]
'Enero'
y éstas se pueden operar:
'La temperatura máxima en Bogotá el '+ temperatura[1]+' de '+temperatura[0]+' del 2021 fue de '+str(temperatura[-1])
'La temperatura máxima en Bogotá el 01 de Enero del 2021 fue de 19'
¿Qué pasa si intentamos modificar una entrada de una tupla?
temperatura[0]='hola'
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [17], in <cell line: 1>()
----> 1 temperatura[0]='hola'
TypeError: 'tuple' object does not support item assignment
Como lo comentamos antes, las tuplas son inmutables.
Para “agregar” elementos a una tupla empleamos el operador +=
, de la misma manera que lo hicimos con las listas. Para las tuplas no disponemos del método append
. Es importante tener en cuenta que al “agregar”, lo que en realidad estamos haciendo es crear una nueva tupla, como podemos ver a continuación:
id(tupla1elemento)
140632800957152
tupla1elemento += ('a',)
tupla1elemento
(23, 'a')
id(tupla1elemento)
140632835582656
Esto ocurre, pues como hemos recalcado, las tuplas son elementos inmutables, pero pueden contener elementos mutables, por ejemplo:
tupla1elemento += ([1,2,3,4],)
tupla1elemento
(23, 'a', [1, 2, 3, 4])
id(tupla1elemento)
140632801261248
tupla1elemento[2]=1
#genererá un error ya que no podemos modificar el elemento de la tupla
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-68-6fafb212dea0> in <module>
----> 1 tupla1elemento[2]=1
2 #genererá un error ya que no podemos modificar el elemento de la tupla
TypeError: 'tuple' object does not support item assignment
#Pero podemos modificar la lista que está dentro de la tupla
tupla1elemento[2][3]='cuatro'
tupla1elemento
(23, 'a', [1, 2, 3, 'cuatro'])
id(tupla1elemento)
#Como se modificó la lista pero no la tupla, sigue siendo el mismo objeto
140632801261248
En este cuaderno, hemos estudiado las herramientas básicas sobre las listas y las tuplas, para así poder tener un mejor desempeño a la hora de elaborar nuestros programas.
Métodos de ordenamiento#
Una de las primeras tareas que se abordan cuando se trabaja con listas es la de ordenar, ya que para diversas labores es necesario que los elementos estén dispuestos de ésta manera.
Para llevar a cabo ésta tarea existen diferentes formas de hacerlo, una forma conocida es mediante el método burbuja, el cual se basa en simples comparaciones e intercambios.
Una lista de n valores se recorre n-1 veces, en las cuales se irán comparando los términos de izquierda a derecha con el siguiente, de tal manera que, si el i-ésimo término es mayor que el que se ubica en la posición i+1, éstos se intercambian de lo contrario se dejan tal cual. En otras palabras, el método lo que hace es ir ubicando el término más grande a la derecha de la lista, motivo por el cual las comparaciones se van reduciendo en cada iteración.
Por ejemplo, en la lista l
que definimos anteriormente, al aplicar las comparaciones del método de la burbuja en la primera iteración, obtenemos lo siguiente:
El nombre de este método es debido a que las comparaciones se hacen en pequeñas burbujas de toda la lista.
Una implementación de este método se puede consultar en la siguiente función:
from time import time
def burbuja(l):
tiempo_inicial = time()
for i in range(1,len(l)-1):
for j in range(len(l)-i-1):
if l[j]>l[j+1]:
l[j],l[j+1] = l[j+1],l[j]
tiempo_transcurrido = time() - tiempo_inicial
print('El proceso tardó {0} segundos'.format(tiempo_transcurrido))
return l
En nuestro código hay tres líneas muy particulares tiempo_inicial = time()
, tiempo_transcurrido = time() - tiempo_inicial
y l[j],l[j+1] = l[j+1],l[j]
. Las dos primeras permiten calcular el tiempo transcurrido en los cálculos para ordenar la lista. La función time()
está disponible gracias a la importación de la libreria con el mismo nombre. Mientras que, la expresión l[j],l[j+1] = l[j+1],l[j]
es una asignación que nos permite ahorrar el uso de una variable auxiliar, en otros lenguajes la asignación sería la siguiente:
l[j] = aux
l[j] = l[j+1]
l[j+1] = aux
Este tipo de asignaciones se conocen como azúcar sintáctico, ya que permiten hace más “dulce” la forma de escribir y leer el código.
Hagamos un ensayo con una lista corta:
burbuja([5,7,3,1,1,3,16])
El proceso tardó 5.0067901611328125e-06 segundos
[1, 1, 3, 3, 5, 7, 16]
Ahora ordenaremos una lista de \(1000\) elementos aleatorios, para tal fin, lo primero que haremos es definirla:
import random
random.seed(2022)
aleatorios = [random.randint(0,1000) for i in range(1000)]
burbuja(aleatorios)
El proceso tardó 0.04517793655395508 segundos
[0,
2,
3,
3,
8,
8,
9,
9,
10,
11,
12,
12,
13,
13,
14,
16,
17,
19,
20,
24,
26,
26,
27,
27,
28,
29,
29,
30,
30,
32,
32,
32,
35,
35,
38,
40,
40,
44,
44,
45,
49,
49,
49,
49,
50,
51,
52,
53,
53,
54,
54,
54,
56,
56,
57,
57,
58,
58,
60,
60,
61,
61,
61,
62,
62,
63,
63,
64,
64,
65,
67,
67,
67,
68,
70,
71,
73,
73,
74,
77,
78,
78,
79,
83,
84,
85,
85,
86,
89,
89,
90,
93,
95,
95,
95,
96,
97,
99,
99,
100,
101,
103,
103,
104,
105,
105,
106,
107,
108,
109,
109,
110,
110,
110,
112,
114,
115,
116,
117,
119,
122,
123,
123,
123,
124,
125,
127,
129,
129,
129,
130,
130,
134,
134,
135,
135,
136,
136,
136,
139,
142,
142,
143,
143,
143,
145,
147,
148,
148,
149,
149,
151,
152,
152,
152,
152,
152,
152,
154,
156,
156,
161,
163,
163,
163,
168,
169,
171,
171,
172,
172,
174,
176,
177,
178,
179,
179,
181,
184,
185,
185,
186,
187,
188,
188,
188,
190,
191,
191,
192,
196,
197,
197,
198,
199,
199,
200,
201,
202,
203,
205,
206,
206,
206,
208,
210,
211,
212,
212,
214,
215,
215,
215,
216,
217,
217,
218,
218,
219,
221,
222,
224,
225,
225,
227,
227,
228,
233,
234,
235,
236,
238,
239,
242,
245,
246,
246,
247,
252,
253,
257,
257,
257,
257,
262,
262,
264,
266,
267,
268,
268,
268,
269,
270,
270,
271,
271,
271,
272,
276,
276,
276,
276,
277,
278,
283,
284,
285,
285,
286,
286,
286,
288,
290,
291,
292,
293,
293,
293,
294,
294,
294,
294,
295,
295,
295,
296,
297,
298,
299,
301,
301,
302,
304,
305,
305,
306,
309,
311,
311,
311,
313,
313,
315,
315,
316,
316,
317,
317,
320,
322,
322,
323,
324,
325,
329,
330,
332,
333,
335,
336,
336,
336,
337,
337,
338,
339,
340,
341,
342,
342,
344,
344,
345,
346,
347,
347,
348,
348,
349,
349,
350,
350,
350,
355,
355,
355,
359,
361,
362,
364,
368,
371,
372,
374,
374,
374,
376,
376,
377,
379,
379,
380,
381,
383,
383,
386,
387,
388,
389,
392,
392,
394,
397,
397,
397,
397,
399,
399,
400,
402,
402,
402,
402,
403,
405,
405,
406,
408,
408,
409,
409,
409,
410,
410,
413,
414,
415,
416,
416,
417,
421,
422,
423,
423,
425,
425,
427,
430,
431,
431,
431,
431,
432,
433,
434,
435,
435,
436,
439,
439,
441,
441,
442,
442,
442,
443,
444,
444,
445,
445,
447,
447,
447,
448,
448,
448,
449,
451,
451,
452,
453,
453,
455,
456,
457,
458,
459,
462,
462,
462,
463,
463,
464,
465,
466,
467,
467,
467,
469,
472,
473,
475,
475,
476,
476,
476,
477,
477,
481,
481,
484,
485,
485,
485,
487,
487,
487,
488,
488,
490,
490,
491,
493,
494,
495,
495,
497,
497,
498,
500,
500,
501,
502,
503,
503,
504,
508,
509,
509,
509,
510,
510,
511,
511,
512,
516,
519,
520,
522,
523,
523,
523,
525,
526,
526,
528,
528,
528,
529,
530,
531,
532,
533,
533,
534,
535,
535,
538,
538,
541,
542,
542,
544,
544,
544,
544,
545,
545,
546,
546,
546,
551,
552,
552,
555,
556,
558,
560,
560,
560,
562,
562,
562,
563,
564,
565,
567,
567,
573,
573,
573,
575,
575,
577,
578,
579,
580,
580,
580,
582,
582,
582,
583,
584,
584,
585,
586,
587,
587,
589,
590,
593,
597,
599,
601,
603,
603,
603,
605,
605,
607,
608,
610,
611,
613,
613,
614,
615,
615,
617,
618,
619,
619,
620,
621,
622,
623,
623,
628,
630,
631,
633,
633,
635,
635,
637,
637,
638,
640,
641,
641,
644,
645,
645,
645,
645,
645,
645,
646,
646,
647,
648,
649,
650,
651,
654,
655,
657,
658,
659,
660,
661,
664,
667,
669,
670,
670,
672,
672,
675,
677,
679,
681,
682,
682,
683,
683,
684,
685,
685,
686,
686,
687,
688,
688,
689,
689,
690,
691,
691,
692,
693,
693,
694,
695,
695,
696,
696,
698,
699,
699,
699,
701,
701,
701,
702,
702,
703,
703,
703,
704,
704,
706,
708,
708,
708,
711,
712,
713,
714,
715,
716,
716,
717,
718,
719,
721,
722,
722,
723,
723,
724,
724,
726,
732,
734,
734,
734,
734,
738,
740,
740,
742,
742,
742,
742,
743,
743,
744,
744,
745,
745,
746,
747,
750,
751,
751,
751,
752,
753,
753,
755,
756,
758,
758,
758,
759,
759,
759,
760,
760,
761,
761,
762,
762,
763,
764,
767,
769,
770,
770,
771,
771,
772,
773,
775,
775,
775,
779,
779,
779,
780,
782,
782,
783,
785,
786,
786,
787,
787,
788,
788,
792,
792,
792,
793,
795,
796,
797,
798,
798,
799,
801,
801,
802,
805,
805,
806,
806,
812,
812,
815,
815,
816,
817,
817,
817,
822,
823,
824,
824,
824,
827,
827,
827,
830,
831,
831,
831,
832,
833,
833,
836,
837,
837,
837,
838,
840,
840,
840,
841,
843,
843,
844,
846,
847,
847,
848,
848,
848,
849,
849,
850,
851,
853,
854,
855,
855,
855,
857,
857,
858,
860,
861,
865,
865,
870,
871,
872,
872,
873,
873,
877,
877,
879,
879,
879,
881,
881,
881,
884,
888,
891,
891,
892,
893,
894,
894,
895,
896,
896,
897,
898,
899,
899,
900,
901,
903,
903,
903,
904,
904,
907,
907,
908,
910,
910,
910,
911,
913,
913,
913,
915,
915,
915,
918,
919,
920,
920,
921,
921,
923,
926,
927,
927,
929,
930,
931,
932,
932,
932,
933,
934,
934,
935,
935,
936,
937,
938,
938,
939,
940,
940,
942,
944,
945,
945,
946,
947,
949,
949,
950,
951,
951,
951,
952,
952,
953,
953,
954,
955,
956,
956,
957,
958,
959,
962,
962,
964,
965,
966,
966,
967,
968,
968,
968,
972,
973,
973,
973,
973,
974,
974,
975,
976,
976,
977,
980,
981,
982,
984,
984,
985,
986,
987,
988,
989,
990,
990,
991,
991,
992,
992,
994,
998,
998,
999,
1000,
314]
Otra forma, quizá un poco más artesanal, se puede expresar de la siguiente manera:
Busque el menor elemento de toda la lista, almacene dicho valor como el primer elemento de otra lista y elimine el valor de la lista original. De la nueva lista busque el elemento menor, guardelo como el siguiente valor en la lista creada y elimine el valor de la lista original. Repita el proceso hasta que no queden elementos en la lista original.
Esta tarea la podemos ver programada en el siguiente bloque de código:
a = [1,2,3,4,5,6]
len(a)
6
b = a[0:2]
b= b+ a[3:6]
b
[1, 2, 4, 5, 6]
a=b
a[3:6]
[5, 6]
a[0:2]
[1, 2]
def ordenamiento1(l):
tiempo_inicial = time()
m = []
for i in range(len(l)):
Min = l[0]
for j in l:
if j < Min:
Min = j
m.append(Min)
aux = l[0:l.index(Min)]
aux = aux + l[l.index(Min)+1:len(a)+1]
l = aux
tiempo_transcurrido = time() - tiempo_inicial
print('El proceso tardó {0} segundos'.format(tiempo_transcurrido))
return m
Probemos con la lista corta:
ordenamiento1([5,7,3,1,1,3,16])
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-83-f352f94c0b9c> in <module>
----> 1 ordenamiento1([5,7,3,1,1,3,16])
<ipython-input-82-e22822f1cd7f> in ordenamiento1(l)
3 m = []
4 for i in range(len(l)):
----> 5 Min = l[0]
6 for j in l:
7 if j < Min:
IndexError: list index out of range
random.seed(2022)
aleatorios = [random.randint(0,1000) for i in range(1000)]
#aleatorios
ordenamiento1(aleatorios)
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-85-c50901b0ecb5> in <module>
----> 1 ordenamiento1(aleatorios)
<ipython-input-82-e22822f1cd7f> in ordenamiento1(l)
3 m = []
4 for i in range(len(l)):
----> 5 Min = l[0]
6 for j in l:
7 if j < Min:
IndexError: list index out of range
En Python existe una manera natural de hacerlo y es con la función sorted
o con el método lista.sort()
, en los cuales subyace el método Timsort, los cuales son supremamente eficientes:
l = [5,7,3,1,1,3,16]
sorted(l)
l = [5,7,3,1,1,3,16]
l.sort()
l
[1, 1, 3, 3, 5, 7, 16]
Estas funciones tienen argumentos que pueden ser de gran ayuda para nosotros, por ejemplo, ordenar de mayor a menor la lista, requeriría definir una función nueva para nosotros, pero con éstas predefinidas basta con escribir lo siguiente:
l = [5,7,3,1,1,3,16]
l.sort(reverse=True)
l
[16, 7, 5, 3, 3, 1, 1]
Ejercicio:#
Cree una lista de 400 valores, en los cuales estén almacenadas las ventas de la última semana de un almacén, aplique los métodos vistos en clase y determine cuál de ellos toma menos tiempo en hacerlo.
Filtros#
En muchas ocasiones nos será necesario elegir algunos valores de una lista que cumplan con un cierto criterio, por ejemplo de la lista [10,20,50,70,90,60,40,30,40,8,95,74,69,45]
, extraigamos los valores que son mayores o iguales a 50:
lista = [10,20,50,70,90,60,40,30,40,8,95,74,69,45]
lista_filtrada = []
for i in lista:
if i >= 50:
lista_filtrada.append(i)
lista_filtrada
[50, 70, 90, 60, 95, 74, 69]
lfiltrada = filter(lambda i:i>= 50,lista)
Si observamos el resultado de un filtro, este un objeto tipo filter
, para poder ver su contenido empleamos el comando list
, así:
list(lfiltrada)
[50, 70, 90, 60, 95, 74, 69]
Si deseamos que el filtro venga dado por el resultado de una función, primero debemos definir dicha función y luego aplicamos el filtro, es decir, no podemos emplear funciones lambda
como en el ejemplo anterior:
random.seed(2022)
lista = [random.randint(0,250) for i in range(100)]
def par(x):
return x%2==0
len(list(filter(par,lista)))
42
La escritura de un filtro, es en gerenal, la siguiente:
filter(función,lista)
Ejercicios#
Use la lista de las 400 ventas de la semana anterior creada anteriormente. Calcule el promedio de dicha lista y aplique un filtro sobre ella para conocer la cantidad de ventas que están por encima de dicho valor y las que están por debajo de él. Guarda estas listas como ventassobreprom y ventasbajoprom, respectivamente.
Cree una función que filtre las vocales y aplique el filtro sobre la siguiente cadena:
En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no ha mucho tiempo que vivía un hidalgo de los de lanza en astillero, adarga antigua, rocín flaco y galgo corredor. Una olla de algo más vaca que carnero, salpicón las más noches, duelos y quebrantos los sábados, lantejas los viernes, algún palomino de añadidura los domingos, consumían las tres partes de su hacienda. El resto della concluían sayo de velarte, calzas de velludo para las fiestas, con sus pantuflos de lo mesmo, y los días de entresemana se honraba con su vellorí de lo más fino. Tenía en su casa una ama que pasaba de los cuarenta y una sobrina que no llegaba a los veinte, y un mozo de campo y plaza que así ensillaba el rocín como tomaba la podadera. Frisaba la edad de nuestro hidalgo con los cincuenta años. Era de complexión recia, seco de carnes, enjuto de rostro, gran madrugador y amigo de la caza. Quieren decir que tenía el sobrenombre de «Quijada», o «Quesada», que en esto hay alguna diferencia en los autores que deste caso escriben, aunque por conjeturas verisímilesII se deja entender que se llamaba «Quijana»III, . Pero esto importa poco a nuestro cuento: basta que en la narración dél no se salga un punto de la verdad.
Don quijote de la mancha - Miguel de Cervantes Saavedra
Mapear#
En otras oportunidades necesitaremos aplicar una función sobre todos los elementos de la lista, es allí cuando aplicamos la función map
. El resultado de esta función es un objeto tipo map
el cual se puede volver una lista de la misma manera como hicimos con los filtros, por ejemplo
def f1(x):
return x**2+1
list(map(f1,[1,2,3,4,5]))
[2, 5, 10, 17, 26]
#Una forma equivalente es emplear las listas por comprensión
[f1(x) for x in [1,2,3,4,5]]
[2, 5, 10, 17, 26]
La diferencia entre map
y filter
, es que en map
aplicamos una función sobre cada elemento de la lista y en filter
aplicamos una función booleana sobre cada elemento de la lista y seleccionamos los que tienen como resultado True
, es decir, aplicamos un criterio de selección booleano.
Los mapeos se pueden aplicar sobre cadenas de caracteres, por ejemplo:
cadena = list('Hoy es un gran día para aprender más herramientas de programación')
list(map(lambda x:x.upper(),cadena))
['H',
'O',
'Y',
' ',
'E',
'S',
' ',
'U',
'N',
' ',
'G',
'R',
'A',
'N',
' ',
'D',
'Í',
'A',
' ',
'P',
'A',
'R',
'A',
' ',
'A',
'P',
'R',
'E',
'N',
'D',
'E',
'R',
' ',
'M',
'Á',
'S',
' ',
'H',
'E',
'R',
'R',
'A',
'M',
'I',
'E',
'N',
'T',
'A',
'S',
' ',
'D',
'E',
' ',
'P',
'R',
'O',
'G',
'R',
'A',
'M',
'A',
'C',
'I',
'Ó',
'N']
También podemos aplicar los mapeos sobre varias listas, siempre que la función lo permita:
nume1 = [1, 2, 3]
nume2 = [4, 5, 6]
result = map(lambda x, y: x + y, nume1, nume2)
print(list(result))
[5, 7, 9]
Ejercicio#
Aplica un mapeo sobre las listas ventassobreprom y ventasbajoprom, para obtener los valores de las ventas sin IVA, suponiendo que todos los productos consumidos están gravados con éste impuesto. A estas listas sería convieniente nombrarlas ventassobreprom_iva y ventasbajoprom_iva.
Reducir#
La función reduce
del paquete functools
, es una útil herramienta cuando deseamos aplicar una función sobre una lista y sus resultados de manera sucesiva. Por ejemplo, para calcular la suma de los elementos de una lista sabemos que existe la función sum
, pero de manera alternativa podemos ejecutar el siguiente código:
from functools import reduce
reduce(lambda x,y:x+y,[1,2,3,4,5])
15
def fun(x,y):
return x+y
reduce(fun,[1,2,3,4,5])
15
Notemos que la función reduce
se aplica de izquierda a derecha, y la función que se aplica sobre la lista debe tener dos argumentos y su resultado es la acumulación de los resultados obtenidos de dicha función sobre la lista.
El siguiente diagrama ayuda a entender de mejor manera su funcionamiento:
reduce
tiene un argumento adicional, el cual es opcional, dicho argumento es el valor inicial, por ejemplo, el siguiente resultado inicia en \(10\) y a eso le suma \(1\), al resultado luego le suma \(2\) y así hasta agotar la lista:
reduce(fun,[1,2,3,4,5],10)
25
En general las reducciones se escriben de la siguiente manera:
from functools import reduce
reduce(función,lista,valor_inicial(opcional))
Ejercicios:#
Halle el mínimo de las listas ventassobreprom_iva y ventasbajoprom_iva, empleando
reduce
y una función lambda.Halle el máximo de las listas ventassobreprom_iva y ventasbajoprom_iva, empleando
reduce
y una función lambda.Cree una función de dos argumentos (\(1\) o \(0\)) que verifique la tabla de verdad del operador lógico Y. Utilice un
reduce
sobre diferentes listas de unos y ceros. ¿Qué puede concluir?Cree una función de dos argumentos (\(1\) o \(0\)) que verifique la tabla de verdad del operador lógico O. Utilice un
reduce
sobre diferentes listas de unos y ceros. ¿Qué puede concluir?
Estas herramientas que hemos adquirido durante el cuaderno, serán de gran utilidad en cursos futuros, en especial cuando se aborden las bases de datos. Por ello es fundamental que se reconozcan las diferencias entre los filtros, mapeos y reducciones:
Función |
Descripción |
Argumentos |
---|---|---|
filtro |
verifica si se cumple una y extrae una sublista de la lista dada |
función, lista |
mapeo |
Aplica una función a cada elemento de una lista dada |
función, lista |
reducción |
Aplica una función sobre una lista de manera reiterada, hasta reducirla a un único valor |
función, lista, valor inicial(opcional) |
Observación: Los filtros, mapeos y reducciones que vimos específicamente para listas, se pueden aplicar también sobre cualquier objeto iterable, es decir, listas, tuplas, diccionarios y conjuntos.
Listas n-dimensionales#
Para darnos una idea, iniciaremos tratando lo que son listas bidimensionales.
Consideremos las siguientes listas:
l1 = [0,1,2,3]
l2 = [10,11,12,13]
l3 = [20,21,22,23]
Partiendo de ellas, podemos obtener la siguiente lista:
L = [l1,l2,l3]
L
[[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
L
es una lista, y sus elementos son listas, es decir, es una lista de listas. Para acceder a un elemento en particular necesitamos tener dos índices, uno para acceder a la lista L
y otro para la lista en la cual nos ubiquemos (l1
, l2
, l3
). Por ejemplo, para acceder a la primera lista y a su primer elemento escribimos así:
L[0][0]
0
Para entender un poco mejor la distribución de las listas de listas, podemos visualizarlas como una matriz, en la que, las filas van indicadas por el primer índice y las columnas por el segundo:
Siguiendo esta idea, si quisiéramos sumar el elemento de la fila \(1\) columna \(2\), con el de la fila \(2\) columna \(1\), emplearíamos la siguiente línea de código:
L[1][2]+L[2][1]
33
Para un arreglo arbitrario a
, la idea es la misma, el primer índice es para las filas y el segundo para las columnas:
Esta misma idea se puede ampliar a tres dimensiones y más, en tres dimensiones podemos todavía visualizar la organización de los datos empleando un cubo, así: es decir, es un arreglo de matrices, como por ejemplo:
Cubo = [[[1,2],[3,4],[5,6]],[[7,8,9],[10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
Cubo
[[[1, 2], [3, 4], [5, 6]],
[[7, 8, 9], [10, 11, 12]],
[[13, 14, 15, 16], [17, 18, 19, 20], [21, 22, 23, 24]]]
Cubo[1]
[[7, 8, 9], [10, 11, 12]]
Cubo[1][0]
[7, 8, 9]
Cubo[1][0][2]
9
Cierre#
Las listas y las tuplas tienen una gran cantidad de aplicaciones, por eso entender el momento y la forma de usarlas es muy importante, ya que las listas son objetos mutables, mientras que las tuplas no, es por esto que si necesitamos modificar alguna de nuestras entradas luego de haber definido el objeto, se debe emplear una lista, pero si deseamos “proteger” las entradas de nuesto objeto, debemos emplear una tupla.