3.2. Tuplas, listas y, de nuevo, cadenas#

3.2.1. Tuplas#

Referencia

https://docs.python.org/3.5/library/stdtypes.html#sequence-types-list-tuple-range

Secuencias inmutables de objetos de cualquier tipo

t = (2, 3., 'abd', [3, True], (4,), (4.7, 'a'), ())
t
(2, 3.0, 'abd', [3, True], (4,), (4.7, 'a'), ())
a = 3, True
a
(3, True)

Observadad que la tupla con un solo elemento lleva una coma

No se pueden reasignar los elementos de una tupla. POr esto son objetos inmutables. Esta es la principal diferencia entre las tuplas y las listas. La celda de abajo debe dar un error.

t[1] = 1
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [5], in <cell line: 1>()
----> 1 t[1] = 1

TypeError: 'tuple' object does not support item assignment

3.2.1.1. Algunos usos de las tuplas#

Empaquetar valores:

Cuando se introduce una secuencia de valores, que pueden ser de diferentes tipos, se genera una tupla

x = 3
y = 5.8
z = 23
t1 = x, y, x
t1
(3, 5.8, 3)

Desempaquetar valores:

t2 = (4.5, 7.2, 3.)
u, v, w = t2
u
4.5

Asignación simultánea de valores:

p, q = 'abc', 'xyz'
q
'xyz'

Intercambio de valores entre dos variables:

a = 3
b = 2
a, b = b, a
a, b
(2, 3)

Una forma más larga

a = 3
b = 2
aux = b
b = a
a = aux
a, b
(2, 3)

3.2.2. Operaciones para los tres tipos#

c = "esto es una cadena" # c es una cadena

t = (1,3,6,3,4,5)        # t es una tupla 

l = [1,3,6,3,4,5]        # l es una lista

Indexado (“indexing”): Como seleccionar una caracter de la cadena o un elemento de la tupla o de la lista.

c[0]
'e'
t[0]
1
l[0]
1

Troceado (”slicing”): Como seleccionar una trozo de la cadena, de la tupla o de la lista: subcadenas, sublistas y subtuplas

c[2:5]
'to '
t[2:5]
(6, 3, 4)
l[2:5]
[6, 3, 4]
c[2:], t[:-1], l[1:2]
('to es una cadena', (1, 3, 6, 3, 4), [3])
c[::2], t[::-1], l[::2]
('et suacdn', (5, 4, 3, 6, 3, 1), [1, 6, 4])

Concatenar: Como unir cadenas, tuplas o listas.

c1 = c + " con otra"
c1
'esto es una cadena con otra'
t1 = t + (7,15)
t1
(1, 3, 6, 3, 4, 5, 7, 15)
l1= l + [20,56]
l1
[1, 3, 6, 3, 4, 5, 20, 56]
c2 = c1 + 'a'
t2 = (7, ) + t1
l2 = l1 + [(3, 0)]
c2, t2, l2
('esto es una cadena con otraa',
 (7, 1, 3, 6, 3, 4, 5, 7, 15),
 [1, 3, 6, 3, 4, 5, 20, 56, (3, 0)])

Repetición

7 * c1, 2 * t1, 3 * l1
('esto es una cadena con otraesto es una cadena con otraesto es una cadena con otraesto es una cadena con otraesto es una cadena con otraesto es una cadena con otraesto es una cadena con otra',
 (1, 3, 6, 3, 4, 5, 7, 15, 1, 3, 6, 3, 4, 5, 7, 15),
 [1,
  3,
  6,
  3,
  4,
  5,
  20,
  56,
  1,
  3,
  6,
  3,
  4,
  5,
  20,
  56,
  1,
  3,
  6,
  3,
  4,
  5,
  20,
  56])

Pertenencia

'a' in c1, 'ab' not in t1, 1 in l1
(True, True, True)

3.2.3. Funciones para los tres tipos#

Lista de funciones propias de Python

3.2.3.1. Longitud#

len(c1), len(t1), len(l1)
(27, 8, 8)

3.2.3.2. Max y min#

Los elementos del objeto deben de ser comparables; deben de ser del mismo tipo

max(c1), min((3, 7, -20)), max(['ab', '1cb', 'W'])
('u', -20, 'ab')

3.2.3.3. Ordenar#

La función del nucleo de Python sorted() proporciona un procedimiento para ordenar este tipo de objetos (cadenas, tuplas o listas) si están formadas por elementos del mismo tipo. Por ejemplo: todos son cadenas, todos son números. Esta función convierte el objeto en una lista y después la ordena. La lista resultante estrá formada por objetos del mismo tipo.

c3 = 'ceha4'
t3 = (15, 4, 7, 8, 10, 0)
t4 = ('a', 'We', 'hn', '12')
l3 = [15, 4, 7, 8, 10, 0.3]
l4 = ['a', 'We', 'hn', '12']
sorted(c3), sorted(t3), sorted(t4), sorted(l3), sorted(l4)
(['4', 'a', 'c', 'e', 'h'],
 [0, 4, 7, 8, 10, 15],
 ['12', 'We', 'a', 'hn'],
 [0.3, 4, 7, 8, 10, 15],
 ['12', 'We', 'a', 'hn'])
l5 = ['a', 'We', 'hn', '12', 1]
sorted(l5)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [33], in <cell line: 2>()
      1 l5 = ['a', 'We', 'hn', '12', 1]
----> 2 sorted(l5)

TypeError: '<' not supported between instances of 'int' and 'str'

También funciona con tipos binarios

l6 = [True, False]
sorted(l6)
[False, True]

3.2.4. Iteración#

Con tuplas: sumar los dígitos de un número entero positivo

# sumar los dígitos de un entero posotivo
# primero iteramos sobre la cadena asociada al entero positivo 
# cada elemento de la cadena lo convertimo en una tupla con un solo elemento  
# a cada iteraión se concatena esta cada cadena a la anterior
c = 743
t = ()
for p in str(c):
    t += (int(p),)
t
(7, 4, 3)
# ahora se suman los elementos de la tupla formada por enteros positivos
suma = 0
for p in t:
    suma += p
suma
14
# función para sumar los dígitos de un número entero positivo 
# se podría haber hecho con listas
# obsérvese como se convierte  el entero en cadena para poder iterar 
def suma_digitos(entero):
    temp = ()
    rsltd = 0
    for p in str(entero):
        temp += (int(p),)
    for q in temp:
        rsltd += q
    return rsltd

z = suma_digitos(346)
z
13

Formar una tupla con los tipos de los elementos de una tupla. Sería lo mismo para una lista

# formar una tupla con los tipos de los elementos de una tupla
rsltd = ()
for p in t1:
    rsltd += (type(p),)
rsltd
(int, int, int, int, int, int, int, int)

Considerar una tupla formada por enteros, cadenas, listas o tuplas. Vamos a escribir el código para generar una tupla con la longitud de los elementos de una lista del tipo anterior asignando la suma de sus dígitos a los enteros de dicha lista.

# formar una lista con la longitud de los elementos de una lista
# si es un entero se añade a la lista la suma de los dígitos del entero positivo
l = ()
for p in l1:
    if type(p) == int:
        aux = str(abs(p))
        l += (suma_digitos(aux),)
    else:
        l += (len(p),)
l
(1, 3, 6, 3, 4, 5, 2, 11)

3.2.5. Métodos para los tres tipos#

3.2.5.1. Índice#

Devuelve el índice de la primera vez que aparece el elemento especificado. Si este elemento no existe, se produce un error

c1 = 'cbedfg'
t1 = (1, 'ab', (3,))
l1 = [7, [9, 1, 7], 'mn']
c1.index('c'), t1.index('ab'), l1.index([9, 1, 7])
(0, 1, 1)

El siguiente método para cadenas devuelve el entero -1 cuando no existe el elmento especificado

# solo para cadenas
c1.find('c'), c1.find('H')
(0, -1)

En estos dos métodos se puede restringir el segmento de búsqueda. Por ejemplo:

l1.index(7, 0, -1)
0

3.2.5.2. Contar#

c1.count('z'), t1.count('ab'), t1.count('a'), l1.count('z')
(0, 1, 0, 0)

Para las cadenas se puede restrigir el segmento de búsqueda no para listas ni para tuplas

'abacdefga'.count('a')
3
'abacdefga'.count('a', 0, -1)
2
t1.count((3,), 0, 1)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [47], in <cell line: 1>()
----> 1 t1.count((3,), 0, 1)

TypeError: count() takes exactly one argument (3 given)

3.2.6. Métodos para cadenas#

https://docs.python.org/3.5/library/stdtypes.html#string-methods

3.2.6.1. Reemplazar#

c1 = 'cbedfg'
c1.replace('c', 'z'), c1
('zbedfg', 'cbedfg')

3.2.6.2. Mayúsculas y minúsculas#

c1 = 'cbedfg'
c1.capitalize(), c1.upper(), c1.islower(), c1.swapcase(), c1
('Cbedfg', 'CBEDFG', True, 'CBEDFG', 'cbedfg')
c1.capitalize().lower().upper()
'CBEDFG'

3.2.6.3. Métodos de listas que también son de cadenas#

c1.index('c')
0
c1.count('e')
1

También se pueden usar restringiendo el campo de búsqueda

c1.index('g', 0, )
5
c1.index('c', 1, 3)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Input In [54], in <cell line: 1>()
----> 1 c1.index('c', 1, 3)

ValueError: substring not found
c1.count('e', 3, -1)
0
c1.count('g', 0, )
1

3.2.7. Cadenas y listas#

3.2.7.1. Hacer listas a partir de cadenas#

  1. Todos los elementos de la cadena pasan a elementos de un lista de caracteres con el mismo orden

c1 = 'am de ?_-&'
list(c1)
['a', 'm', ' ', 'd', 'e', ' ', '?', '_', '-', '&']
  1. Se hace una lista con trozos de una cadena utilizando como separador el elemento que se elija de la cadena. Este elemento no se incluye.

Aquí se harán dos trozos ya que el caracter 'e' aparece solo una vez

c1.split('e')
['am d', ' ?_-&']

Separar las palabras de un texto: ahora se harán muchos trozos porque el espacio en blanco aparece más de una vez

'Nos vamos a los puertos'.split(' ')
['Nos', 'vamos', 'a', 'los', 'puertos']

El método split se podría utilizar para contar las palabras de un texto:

texto = 'se habían tomado diversas medidas para proteger a la población'

M = texto.split(' ')

len(M)
10

Sin argumento, el método split() divide por los espacios en blanco

'uno dos tres'.split()
['uno', 'dos', 'tres']

3.2.7.2. Hacer cadenas a partir de listas#

El método, .joint(), es un método de las cadenas. Se aplica a una cadena y toma como argumento una lista: produce una cadena con los elmentos de la lista unidos por la cadena a la que se aplica

c1 = 'hola y adios'
l1 = list(c1)
l2 = c1.split(' ')
l1
['h', 'o', 'l', 'a', ' ', 'y', ' ', 'a', 'd', 'i', 'o', 's']
l2
['hola', 'y', 'adios']

Ahora formamos cadenas “pegando” los trozos que hay en una lista. el “pegamento” será una cadean. Abajo utilizamos las cadenas '_' y ' ', como “pegamento”.

c2 = '_'.join(l1)
c3 = '_'.join(l2)
c4 = ' '.join(l2)
c2
'h_o_l_a_ _y_ _a_d_i_o_s'
c3
'hola_y_adios'
c4
'hola y adios'

Observad que el argumento del método .join() debe ser una lista formada por cadenas

'.'.join([3, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [69], in <cell line: 1>()
----> 1 '.'.join([3, 2])

TypeError: sequence item 0: expected str instance, int found
'.'.join(['3', '2'])
'3.2'

Convertir cadenas en listas y viceversa

Reelaborando lo anterior, as siguientes instrucciones resultan útiles si deseamos modificar cadenas:

Crear una lista con todos los caracteres de la cadena

list('hola')
['h', 'o', 'l', 'a']
Crear una cadena uniendo los elemento de la lista usando como "pegamento" lo que se escribe entre comillas
  Input In [72]
    Crear una cadena uniendo los elemento de la lista usando como "pegamento" lo que se escribe entre comillas
          ^
SyntaxError: invalid syntax
''.join(['h', 'o', 'l', 'a'])
'hola'
'O'.join(['h', 'o', 'l', 'a'])
'hOoOlOa'

Modificar una cadena

El uso de list y join resulta útil si queremos modificar una cadena (algo que no se puede hacer directamente).

El código de abajo remplaza las letras e de cadean por la letra X .

texto = 'las abejas tienen una organización muy compleja'

M = list(texto)
for u in range(len(M)):
    if M[u] == 'e':
        M[u] = 'X'
''.join(M)
'las abXjas tiXnXn una organización muy complXja'

3.2.8. Ejemplos#

  1. Poner del revés una cadena

c = 'abcd'
c_al_revés = ''
for l in c:
    c_al_revés = l + c_al_revés
c_al_revés
'dcba'

Observad

'abcd'[::-1]
'dcba'
  1. Define una función, suma(n), que reciba como argumento un número entero n y devuelva la suma de sus dígitos.

def suma(n):
    s=0
    for i in str(n):
        s+=int(i)
    return s
suma(12345)
15
  1. Define una función, Lsuma(L), que reciba como argumento una lista L de números enteros y devuelva una lista con las sumas de los dígitos de cada uno de ellos. Utiliza la función anterior.

def Lsuma(L):
    Ls=[]
    for i in L:
        Ls.append(suma(i))
    return Ls    
Lsuma([12,13,56,7])
[3, 4, 11, 7]
  1. Define una función, suma(x), que reciba como argumento un número real x y devuelva la suma de sus dígitos.

def suma(x):
    s=0
    for i in str(x):
        if i!=".":
            s+=int(i)
    return s
suma(12345.6)
21
  1. Define una función encontrar1(L,e) que recibe como argumentos una lista L y un valor e y devuelve True si e es un elemento de la lista L

def encontrar1(L,e):
    if e in L:
        return True
encontrar1([1,2,3,4],2)
True
encontrar1([1,2,3,4],0)
  1. Define una función encontrar2(L,e) que recibe como argumentos una lista L y un valor e y devuelve False si e no es un elemento de la lista L

def encontrar2(L,e):
    if e not in L:
        return False
encontrar2([1,2,3,4],'s')
False
encontrar2([1,2,3,4],1)

Otra versión, utilizando pass

def encontrar3(L,e):
    if e in L:
        pass
    else:
        return False
encontrar3([1,2,3,4],1)
encontrar3([1,2,3,4],'s')
False
  1. Define una función tuplaalista1(t) que recibe como argumento una tupla t y devuelve una lista con los mismos elementos

def tuplaalista1(t):
    l = []
    for i in t:
        l.append(i)
    return l    
tuplaalista1((1,2,"a",10))
[1, 2, 'a', 10]

Otra versión

def tuplaalista2(t):
    return list(t)
tuplaalista2((1,2,"a",10))
[1, 2, 'a', 10]
  1. Define una función tuplaalista2(t) que recibe como argumento una tupla t y devuelve una lista con los elementos de t no repetidos

def tuplaalista2(t):
    l = []
    for i in t:
        if i not in l:
            l.append(i)
    return l    
tuplaalista2((1,2,"a",10,3,10,"a"))
[1, 2, 'a', 10, 3]

Otra versión

def tuplaalista3(t):
    l = []
    for i in t:
        if l.count(i)==0:
            l.append(i)
    return l    
tuplaalista3((1,2,"a",10,3,10,"a"))
[1, 2, 'a', 10, 3]
  1. Define una función cadenaalista1(c) que recibe como argumento una cadena c y devuelve una lista cuyos elementos son los caracteres de c (nuestra función list())

def cadenaalista1(c): #Es igual que la función tuplaalista1
    l = []
    for i in c:
        l.append(i)
    return l    
cadenaalista1("cadena ")
['c', 'a', 'd', 'e', 'n', 'a', ' ']

Otra versión ahora se utiliza la fubnción list()

def cadenaalista1_1(c): # Utilizamos la función lista()
    return list(c)
cadenaalista1_1("cadena ")
['c', 'a', 'd', 'e', 'n', 'a', ' ']
  1. Define una función cadenaalista2(c) que recibe como argumento una cadena c y devuelve una lista cuyos elementos son los caracteres de c no repetidos

def cadenaalista2(c): #Es igual que la función tuplaalista2
    l = []
    for i in c:
        if i not in l:
            l.append(i)
    return l   
cadenaalista2("cadena de prueba")
['c', 'a', 'd', 'e', 'n', ' ', 'p', 'r', 'u', 'b']

Otra versión

def cadenaalista2_1(c):
    l = list(c)
    for i in l:
        if l.count(i) != 0:
            l.remove(i)
    return l   
cadenaalista2_1("esto es una cadena de prueba")
['o', 's', ' ', 'a', 'e', 'n', 'a', ' ', 'd', 'e', ' ', 'r', 'e', 'a']

¿Que ha ocurrido?. ¿Hemos obtenido el resultado que esperábamos?.

  1. Define una función palabras(c) que recibe como argumento una cadena c y devuelve una lista cuyos elementos son las palabras que contenga cadena

def palabras(c):
    l = c.split(' ')
    return l
palabras("Esto es una cadena de prueba")
['Esto', 'es', 'una', 'cadena', 'de', 'prueba']
  1. Define una función letras(c,i) que recibe como argumento una cadena c y un índice i y devuelve una lista cuyos elementos son las letras con índice i de las palabras de la cadena c

def letras(c,i):
    l = c.split(' ')
    L = list(l[i])
    return L
letras("esto es una cadena de prueba",1)
['e', 's']

3.2.9. Ejercicios#

  1. Definir la función lista_palabras(texto) que devuelva una lista con las palabras de texto.

  2. Definir la función invierte_palabras(texto) que devuelva un nuevo texto con las palabras de texto en orden inverso (de la última a la primera).

  3. Definir la función unir_numeros(lista) que devuelve un número entero que se obtiene escribiendo sucesivamente los números enteros que forman lista. Ejemplo: unir_numeros([1,23,61]); devuelve 12361

  4. A la variable texto se le ha asignado una cadena. Escribir un programa en Python que determine la palabra más larga contenida en texto e imprima el resultado con el siguiente formato: La palabra más larga es (resultado) Ejemplo: Si texto = ‘la fauna africana se están quedando sin espacio para vivir’ el programa debe imprimir ‘La palabra más larga es depredadores’

  5. Definir la función ordenar(lista) que devuelva la lista ordenada de modo creciente de los elementos de lista.

  6. Definir la función esta_ordenada(lista) que devuelve True o False según los elementos de lista estén ordenados de modo creciente.