IWI131 Programación


Estructuras de Datos: Tuplas



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

Tuplas

  • Una tupla es una secuencia de valores agrupados.
  • Pueden contener básicamente cualquier cosa.
  • Una tupla sirve para agrupar, como si fueran un único valor, varios valores que por su naturaleza deben ir juntos.
  • Una tupla es inmutable, es decir, no puede ser modificada una vez que ha sido creada.

Creación de Tuplas

  • Usando paréntesis ()
  • Usando la función tuple()

Tupla Vacía

Aunque no tiene mucha utilidad. ¿Por qué?

In [1]:
a = ()
b = tuple()
print(a)
print(b)
()
()

Tupla con elementos

In [5]:
a = (1,2,3,4)
b = tuple(['a', 1, True, [1, 2]])
print(a)
print(b)
(1, 2, 3, 4)
('a', 1, True, [1, 2])
In [5]:
c = tuple([1, 2, 3, 4])
d = tuple((1, 2, 3, 4))
print(c)
print(d)
(1, 2, 3, 4)
(1, 2, 3, 4)

La función tuple(iterable) convierte a tupla el tipo de dato dado por la variable iterable. Cada elemento de iterable es agregado a una tupla.

In [2]:
tup = tuple("abc")
print(tup)
('a', 'b', 'c')

Desempaquetado de Tuplas

Los valores individuales de una tupla pueden ser recuperados asignando la tupla a las variables respectivas. Esto se llama desempaquetar la tupla.

In [1]:
tupla = (1, 2, 3)
a, b, c = tupla
print(tupla)
print(a, b, c)
(1, 2, 3)
1 2 3

Para desempaquetar correctamente debe utilizar tantas variables como elementos posee la tupla.

In [5]:
tupla = (1, 2, 3)
a, b = tupla
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-ae12a64c6800> in <module>
      1 tupla = (1, 2, 3)
----> 2 a, b = tupla

ValueError: too many values to unpack (expected 2)

Además, también es posible extraer los valores usando su índice, al igual que con las listas:

In [7]:
tupla = (1, 2, 3)
print(tupla[1])
2

A diferencia de las listas, los elementos de una tupla no se pueden modificar:

In [8]:
tupla = (1, 2, 3)
tupla[0] = 100
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-970d1eb5a3e2> in <module>
      1 tupla = (1, 2, 3)
----> 2 tupla[0] = 100

TypeError: 'tuple' object does not support item assignment

Usos recomendados

Las tuplas se usan siempre que es necesario agrupar valores. Generalmente, conceptos del mundo real son representados como tuplas que agrupan información sobre ellos.

In [10]:
posicion_alfil = (7, 6)
alumno = ('Fulano', 'De Tal', '201199001-1')
carta = (5, 'corazones')
fecha = (2011, 4, 12)
triangulo = ((5, 1), (2, 4), (-2, 0))
personaje = ('Arturo Prat', (1848, 4, 3),
             (1879, 5, 21))
In [11]:
punto = (6.6, -2.4, 3.7)
x, y, z = punto
print(x)
6.6
In [12]:
personaje = ("Bernardo O'Higgins", (1778, 8, 20), (1842, 10, 24))
nombre, nacimiento, defuncion = personaje
an, mn, dn = nacimiento
ad, md, dd = defuncion
print(ad - an)
64

Comparación de Tuplas

Dos tuplas son iguales cuando tienen el mismo tamaño y cada uno de sus elementos correspondientes tienen el mismo valor:

In [16]:
(1, 2) == (3 // 2, 1 + 1)
Out[16]:
True
In [17]:
(6, 1) == (6, 2)
Out[17]:
False
In [18]:
(6, 1) == (6, 1, 0)
Out[18]:
False

Para determinar si una tupla es menor que otra, se utiliza lo que se denomina orden lexicográfico. Si los elementos en la primera posición de ambas tuplas son distintos, ellos determinan el ordenamiento de las tuplas:

In [19]:
(1, 4, 7) < (2, 0, 0, 1)
Out[19]:
True
In [20]:
(1, 9, 10) < (0, 5)
Out[20]:
False

La primera comparación es True porque 1 < 2. La segunda comparación es False porque 1 > 0. No importa el valor que tengan los siguientes valores, o si una tupla tiene más elementos que la otra.

Si los elementos en la primera posición son iguales, entonces se usa el valor siguiente para hacer la comparación:

In [21]:
(6, 1, 8) < (6, 2, 8)
Out[21]:
True
In [22]:
(6, 1, 8) < (6, 0)
Out[22]:
False

La primera comparación es True porque 6 == 6 y 1 < 2. La segunda comparación es False porque 6 == 6 y 1 > 0 .

Si los elementos respectivos siguen siendo iguales, entonces se sigue probando con los siguientes uno por uno, hasta encontrar dos distintos. Si a una tupla se le acaban los elementos para comparar antes que a la otra, entonces es considerada menor que la otra:

In [2]:
(1, 2) < (1, 2, 4)
Out[2]:
True
In [3]:
(1, 3) < (1, 2, 4)
Out[3]:
False

La primera compación es True porque 1 == 1, 2 == 2, y ahí se acaban los elementos de la primera tupla. La segunda comparación es False porque 1 == 1 y 3 < 2; en este caso sí se alcanza a determinar el resultado antes que se acaben los elementos de la primera tupla.

Algunas operaciones sobre tuplas

Verificar si elemento se encuentra en una tupla

La instrucción in permite verificar si un elemento está contenido en una tupla.

In [23]:
t = (1, 5, 6)
In [24]:
1 in t
Out[24]:
True
In [27]:
3 not in t
Out[27]:
True

Funciones que aceptan tuplas como parámetros

Longitud de una tupla

La función len(tupla) entrega la cantidad de elementos de la tupla ingresada como parámetro.

In [31]:
t = (1,2,3,4,8,10)
print("La cantidad de elementos en la tupla es", len(t))
La cantidad de elementos en la tupla es 6

Suma de los valores de una tupla

Usando la función sum(tupla), se puede determinar la suma de los elementos de una tupla.

In [33]:
sum(t)
Out[33]:
28

Mínimo y Máximo en una tupla de elementos

La función min(tupla) y max(tupla) entrega el valor mínimo y máximo de la tupla ingresada como parámetro.

In [34]:
print(min(t), max(t))
1 10

Ciclo for en tuplas

  • Un ciclo for puede ser usado para iterar sobre tuplas.
In [35]:
tt = tuple(range(10))

for e in tt:
    print(e)
0
1
2
3
4
5
6
7
8
9

Iterables (hasta el momento):

  • Strings
  • Listas
  • range
  • Tuplas

Mezcla de Estructuras: Lista de Tuplas

Algunas veces es necesario integrar varias estructuras para resolver ciertos problemas.

In [39]:
# Opcion 1

ramos = [
    ('Progra', 'IWI-131', 3),
    ('Mate', 'MAT-021', 5),
    ('Física', 'FIS-100', 3),
    ('Ed.Fisica', 'DEW-100', 1),
    ('Inmanente', 'HRW-102', 2)
]

# Iterar sobre la lista de tuplas
for ramo in ramos:
    nombre, sigla, c = ramo
    print(nombre, 'tiene', c, 'creditos')
Progra tiene 3 creditos
Mate tiene 5 creditos
Física tiene 3 creditos
Ed.Fisica tiene 1 creditos
Inmanente tiene 2 creditos
In [13]:
# Opcion 2
ramos = [
    ('Progra', 'IWI-131', 3),
    ('Mate', 'MAT-021', 5),
    ('Física', 'FIS-100', 3),
    ('Ed.Fisica', 'DEW-100', 1),
    ('Inmanente', 'HRW-102', 2)
]

# Iterar sobre la lista de tuplas
for nombre, sigla, c in ramos:
    print(nombre, 'tiene', c, 'creditos')
Progra tiene 3 creditos
Mate tiene 5 creditos
Física tiene 3 creditos
Ed.Fisica tiene 1 creditos
Inmanente tiene 2 creditos

Ordenar una lista de tuplas

In [44]:
star_wars = [
    (4, 'Una nueva Esperanza'),
    (5, 'El Imperio Contraataca'),
    (6, 'El Retorno del Jedi'),
    (1, 'La Amenaza Fantasma'),
    (2, 'El Ataque de los Clones'),
    (3, 'La Venganza de los Siths'),
    (7, 'El Despertar de la Fuerza'),
    (8, 'Los Ultimos Jedi')
]
star_wars
Out[44]:
[(4, 'Una nueva Esperanza'),
 (5, 'El Imperio Contraataca'),
 (6, 'El Retorno del Jedi'),
 (1, 'La Amenaza Fantasma'),
 (2, 'El Ataque de los Clones'),
 (3, 'La Venganza de los Siths'),
 (7, 'El Despertar de la Fuerza'),
 (8, 'Los Ultimos Jedi')]
In [45]:
star_wars.sort()
star_wars
Out[45]:
[(1, 'La Amenaza Fantasma'),
 (2, 'El Ataque de los Clones'),
 (3, 'La Venganza de los Siths'),
 (4, 'Una nueva Esperanza'),
 (5, 'El Imperio Contraataca'),
 (6, 'El Retorno del Jedi'),
 (7, 'El Despertar de la Fuerza'),
 (8, 'Los Ultimos Jedi')]
In [48]:
nums = [(1, 4), (1, 2), (1, 1), (1, 10)]
nums
Out[48]:
[(1, 4), (1, 2), (1, 1), (1, 10)]
In [50]:
nums.sort()
nums
Out[50]:
[(1, 1), (1, 2), (1, 4), (1, 10)]

Para ordenar una lista de tuplas, utiliza el criterio de comparación de tuplas utilizando un orden ascendente.

Ejercicios

1. Escriba una función distancia(p1, p2) que retorne la distancia entre los puntos p1 y p2:

>>> a = (5.1, 7.3, 2.4)
>>> b = (1.1, 2.8, 4.9)
>>> distancia(a, b)
6.5192024052026492
In [1]:
def distancia(p1, p2):
    x1, y1, z1 = p1
    x2, y2, z2 = p2
    dx = x2 - x1
    dy = y2 - y1
    dz = z2 - z1
    return (dx ** 2 + dy ** 2 + dz ** 2) ** 0.5
In [2]:
a = (5.1, 7.3, 2.4)
b = (1.1, 2.8, 4.9)
distancia(a, b)
Out[2]:
6.519202405202649

2. Un polígono está determinado por la lista de sus vértices. Escriba una función perimetro(vertices) que entregue el perímetro del polígono definido por la lista vertices:

>>> p = [(4, 1), (7, 2), (7, 4), (5, 9)]
>>> perimetro(p)
18.609700215601432
In [8]:
# Distancia para puntos en R^2
def distancia(p1, p2):
    (x1, y1), (x2, y2) = p1, p2
    dx, dy = x2 - x1, y2 - y1
    return (dx ** 2 + dy ** 2) ** .5
In [9]:
# Propuesta 1
def perimetro(vertices):
    n = len(vertices)
    suma = 0.0
    for i in range(n):
        a = vertices[i]
        b = vertices[(i + 1) % n]
        suma += distancia(a, b)
    return suma
In [10]:
p = [(4, 1), (7, 2), (7, 4), (5, 9)]
perimetro(p)
Out[10]:
18.609700215601432
In [4]:
# Propuesta 2
def perimetro(vertices):
    n = len(vertices)
    actual = vertices[0:n]
    sgte = vertices[1:n] + [vertices[0]]
    distancias = []
    for i in range(n):
        d = distancia(actual[i], sgte[i])
        distancias.append(d)
    return sum(distancias)
In [11]:
p = [(4, 1), (7, 2), (7, 4), (5, 9)]
perimetro(p)
Out[11]:
18.609700215601432