Estructuras de datos nativas

Hemos visto los tipos de datos simples de Python: int, float, str, etc. Python también tiene algunas tipos de datos complejos:

Tipo Ejemplo Descripción
list [1, 2, 3] colección ordenada
tuple (1, 2, 3) colección ordenada inmutable
dict {'a':1, 'b':2, 'c':3} Mapeo (llave,valor) sin orden
set {1, 2, 3} Colección sin orden de valores únicos

Como ven, lo que introduce el tipo de objetos son los parentesis, corchetes, y llaves con ciertas pequeñas diferencias.

Las listas

Las listas son ordenadas y mutables. Se definen con los valores separados por comas:


In [1]:
L = [2, 3, 5, 7]

Hay una serie de métodos disponibles para las listas, veamos algunos de los más comunes:


In [2]:
# largo de la lista
len(L)


Out[2]:
4

In [3]:
# agregar un valor
L.append(11)
L


Out[3]:
[2, 3, 5, 7, 11]

In [4]:
# el op de suma concatena listas
L + [13, 17, 19]


Out[4]:
[2, 3, 5, 7, 11, 13, 17, 19]

In [5]:
# sort() ordena "in place"
L = [2, 5, 1, 6, 3, 4]
L.sort()
L


Out[5]:
[1, 2, 3, 4, 5, 6]

Hay muchos más métodos que se encuentran en la documentación de Python. RTFM.

Las listas pueden contener cualquier clase de objeto, pero guarda como la estructuran y acceden!


In [6]:
L = [1, 'two', 3.14, [0, 3, 5]]

Indexando y partiendo listas

Python tiene un metodo conveniente para acceder a los diversos valores de las listas o a "rangos" de valores. Esto se hace a través de una notación tipo matricial (bueh, donde los subíndices se cambian por corchetes):


In [7]:
L = [2, 3, 5, 7, 11]

De nuevo, Python usa 0-based indexing para acceder a los miembros:


In [8]:
L[0]


Out[8]:
2

In [9]:
L[1]


Out[9]:
3

Los elementos al final de la lista pueden accederse con índices negativos:


In [10]:
L[-1]


Out[10]:
11

In [11]:
L[-2]


Out[11]:
7

"Indexing" retorna un solo número, "slicing" retorna un rango.


In [12]:
L[0:3]


Out[12]:
[2, 3, 5]

Si sacamos el 0, se entiende igual "desde el principio de la lista"


In [13]:
L[:3]


Out[13]:
[2, 3, 5]

Si dejamos afuera el último índice, se asume el largo de la lista.


In [14]:
L[-3:]


Out[14]:
[5, 7, 11]

También como en el "range" podemos especificar un entero más como "salto", tipo:


In [15]:
L[::2]  # equivalent to L[0:len(L):2]


Out[15]:
[2, 5, 11]

Si especificamos un "salto" negativo, revertimos la lista:


In [16]:
L[::-1]


Out[16]:
[11, 7, 5, 3, 2]

No solo podemos usar "indexing" y "slicing" para acceder a elementos, sino también para asignarlos, por ejemplo:


In [17]:
L[0] = 100
print(L)


[100, 3, 5, 7, 11]

In [18]:
L[1:3] = [55, 56]
print(L)


[100, 55, 56, 7, 11]

Tuplas

Las tuplas son similares a las listas, se definen con paréntesis en vez de corchetes, pero son inmutables, es decir, no se pueden cambiar.


In [19]:
t = (1, 2, 3)
print(t)


(1, 2, 3)

Las tuplas tienen un largo y los elementos se pueden extraer igual que las listas con el índice:


In [20]:
len(t)


Out[20]:
3

In [21]:
t[0]


Out[21]:
1

La principal diferencia es que los valores de las tuplas no se pueden cambiar, son inmutables!


In [22]:
t[1] = 4


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-141c76cb54a2> in <module>()
----> 1 t[1] = 4

TypeError: 'tuple' object does not support item assignment

In [23]:
t.append(4)


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-23-e8bd1632f9dd> in <module>()
----> 1 t.append(4)

AttributeError: 'tuple' object has no attribute 'append'

Las tuplas se usan en Python usualmente para devolver (y tomar) el resultado de funciones que devuelven varios valores:


In [24]:
x = 0.125
x.as_integer_ratio()


Out[24]:
(1, 8)

Y se "agarran" de la siguiente manera:


In [25]:
numerator, denominator = x.as_integer_ratio()
print(numerator / denominator)


0.125

También hay un montón de métodos para tuplas, vean la documentación

Dicts (diccionarios)

Los diccionarios son super flexibles (de hecho los objetos de Python son diccionarios). Se pueden crear a traves de listas de pares llave:valor (key:value) entre llaves:


In [26]:
numbers = {'one':1, 'two':2, 'three':3}

Los miembros del dict se accesed a través de la llave:


In [27]:
numbers['two']


Out[27]:
2

También se pueden agregar nuevos elementos al dict:


In [28]:
numbers['ninety'] = 90
print(numbers)


{'ninety': 90, 'three': 3, 'one': 1, 'two': 2}

En los diccionarios no hay orden. Vean la documentación de esta increible estructura de datos.

Sets (conjuntos)

Los sets son conjuntos (!) no ordenados de elementos únicos (como un set, duh). Se definen como listas (valores separados por comas), pero entre curlys:


In [29]:
primes = {2, 3, 5, 7}
odds = {1, 3, 5, 7, 9}

Igual que los sets matemáticos, a los sets de Python se pueden aplicar operadores como union, interseccion, diferencia, diferencia simétrica, entre otros. Por ejemplo:


In [30]:
# union
primes | odds      # con un op
primes.union(odds) # con el método


Out[30]:
{1, 2, 3, 5, 7, 9}

In [31]:
# intersección
primes & odds             # con un op
primes.intersection(odds) # con un metodo


Out[31]:
{3, 5, 7}

In [32]:
# diferencia
primes - odds           # con un op
primes.difference(odds) # con un metodo


Out[32]:
{2}

In [33]:
# diferencia simétrica: items que aparecen en un solo set
primes ^ odds                     # con op
primes.symmetric_difference(odds) # con metodo


Out[33]:
{1, 2, 9}