Introducción a la programación en Python

clase 05b
Tipos II, sets

sets

Los sets son colecciones no ordenadas de elementos únicos. A diferencia de las secuencias, sus elementos no pueden accederse por indexado ni particionado.
Hay dos typos de sets: set, que es mutable, y frozenset, que es inmutable.
Ambos tipos de sets pueden crearse con las respectivas funciones set() y frozenset().
Estas funciones pueblan el set iterando sobre el argumento dado.

In [3]:
a = set([1, 2, 3, 2, 1, 4, 5, 3])
print(a, type(a), sep='\t')
{1, 2, 3, 4, 5}	<class 'set'>
In [4]:
a = frozenset([1, 2, 3, 2, 1, 4, 5, 3])
print(a, type(a), sep='\t')
frozenset({1, 2, 3, 4, 5})	<class 'frozenset'>

Los elementos de un set son únicos (sin repeticiones dentro del set), y deben ser objetos inmutables: números, cadenas de caracteres, tuples y sets inmutables, pero no listas ni sets mutables.

In [5]:
a = set(["foo", (2, 1, 4), 5, 3])
print(a)
{5, 3, (2, 1, 4), 'foo'}
In [6]:
b = set(["foo", frozenset([2, 1, 4]), 5, 3])
print(b)
{5, 3, frozenset({1, 2, 4}), 'foo'}
In [7]:
c = set(["foo", [2, 1, 4], 5, 3])
print(c)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-8bece9118a07> in <module>
----> 1 c = set(["foo", [2, 1, 4], 5, 3])
      2 print(c)

TypeError: unhashable type: 'list'
In [8]:
d = set(["foo", set([2, 1, 4]), 5, 3])
print(d)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-8-9956b086f13e> in <module>
----> 1 d = set(["foo", set([2, 1, 4]), 5, 3])
      2 print(d)

TypeError: unhashable type: 'set'

Ejemplo 5.2

Crear una función que determine el pitch-class set de una secuencia de alturas dada como argumento. Utilizar para ello la función que devuelve el pitch-class de una altura.

In [9]:
def pitch_a_pc(pitch):
    '''convierte una altura en número de nota MIDI a pitch-class'''
    pc = pitch % 12
    return pc

def pcset(alturas):
    '''devuelve el pitch-class set de una secuencia de alturas'''
    pc_set = set([pitch_a_pc(i) for i in alturas])
    return pc_set

# listas con las alturas en nota MIDI
alturas1 = [77, 63, 59, 54, 64, 71, 66, 57, 68, 76, 73, 65]
alturas2 = [67, 73, 58, 79, 49, 69]
# imprimir el set
print(pcset(alturas1))
print(pcset(alturas2))
print(pcset(alturas1+alturas2))
{1, 3, 4, 5, 6, 8, 9, 11}
{1, 10, 9, 7}
{1, 3, 4, 5, 6, 7, 8, 9, 10, 11}

Métodos y operaciones de sets

len()

Devuelve la longitud de un set.

.copy()

Hace una copia del set.

.difference()

Devuelve la diferencia entre dos sets: todos los elementos que están en el set al cual le aplico el método, pero no en el argumento.

In [10]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
print(set1)
print(set2)
print(set1.difference(set2))
print(set2.difference(set1))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{1, 3, 7}
{8, 9}

.intersection()

Devuelve la intersección entre los sets: todos los elementos que están en ambos.

In [11]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
print(set1)
print(set2)
print(set1.intersection(set2))
print(set2.intersection(set1))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{2, 11, 4, 5}
{2, 11, 4, 5}

.isdisjoint()

Devuelve True si no hay elementos comunes entre los sets.

In [12]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
print(set1)
print(set2)
print(set1.isdisjoint(set2))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
False

.issubset()

Devuelve True si el set es un subconjunto del set argumento.

In [13]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
set3 = set([11, 5, 2, 4])
print(set1)
print(set2)
print(set3)
print(set2.issubset(set1))
print(set3.issubset(set1))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{2, 11, 4, 5}
False
True

.issuperset()

Devuelve True si el set es un superset del set argumento.

In [14]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
set3 = set([11, 5, 2, 4])
print(set1)
print(set2)
print(set3)
print(set1.issuperset(set2))
print(set1.issuperset(set3))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{2, 11, 4, 5}
False
True

.symmetric_difference()

Devuelve todos los elementos que están en un set u otro, pero no en ambos.

In [15]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
print(set1)
print(set2)
print(set1.symmetric_difference(set2))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{1, 3, 7, 8, 9}

.union()

Devuelve un set con todos los elementos que están en alguno de los sets.

In [16]:
set1 = set([4, 3, 11, 7, 5, 2, 1, 4])
set2 = set([11, 5, 9, 2, 4, 8])
print(set1)
print(set2)
print(set1.union(set2))
{1, 2, 3, 4, 5, 7, 11}
{2, 4, 5, 8, 9, 11}
{1, 2, 3, 4, 5, 7, 8, 9, 11}