Python: Conjuntos inmutables con frozenset

Objetivo: presentar el tipo frozenset para la implementación de conjuntos inmutables.

Al igual que las listas encuentran en las tuplas su versión inmutable, los conjuntos, que como vimos quedaban representados por el tipo set, hallan su inalterabilidad a través del tipo frozenset.

Podríamos traducir frozenset por algo así como conjunto congelado, término que muestra claramente su carácter estático. Podemos pensar en un frozenset como en un set en el que no podemos modificar su composición una vez creado.

Veamos cómo creamos un frozenset:

>>> c1 = frozenset({'pradera', 2, 'pimiento'})
>>> c1
frozenset({'pimiento', 2, 'pradera'})

Presta mucha atención: empleamos el constructor frozenset, facilitando, como argumento, entre paréntesis, un conjunto definido explicitamente.

En general, el argumento no tiene por qué ser un conjunto, sino que sirve cualquier tipo de objeto iterable, como una lista. Más adelante hablaremos formalmente de qué significa exactamente eso de ser iterable, pero por el momento quédate con que un iterable es cualquier objeto que puede ser recorrido de principio a fin dentro de un bucle for.

Por lo tanto, la definición anterior también podrías haberla hecho así:

>>> c1 = frozenset(['pradera', 2, 'pimiento'])
>>> c1
frozenset({'pimiento', 2, 'pradera'})

El resultado, como ves, es el mismo empleando corchetes (listas) que llaves (conjuntos). O incluso si facilitas unta tupla como argumento:

>>> c1 = frozenset(('pradera', 2, 'pimiento'))
>>> c1
frozenset({'pimiento', 2, 'pradera'})

Date cuenta de que, aunque estemos facilitando varios datos a través de un conjunto, lista o tupla, en realidad dentro de frozenset hay un único argumento. El siguiente código sería erróneo:

>>> frozenset('pimiento', 2, 'pradera')
Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    frozenset('pimiento', 2, 'pradera')
TypeError: frozenset expected at most 1 arguments, got 3

ya que hemos introducido tres argumentos y, como informa el código de error, cómo máximo admite uno.

En efecto: como máximo un argumento. O, lo que es lo mismo, uno o ninguno.

>>> c2 = frozenset()
>>> c2
frozenset()

Como vemos, cuando no facilitamos ningún argumento, creamos un frozenset vacío.

Las cadenas de caracteres también son iterables, pues pueden ser recorridas de principio a fin con un bucle for. Por lo tanto, también nos pueden servir para generar un frozenset:

>>> c3 = frozenset('pradera')
>>> c3
frozenset({'a', 'p', 'r', 'e', 'd'})

Observa qué ha pasado: se ha descompuesto la cadena en sus caracteres individuales, eliminando las repeticiones. Esto es algo natural, ya que los conjuntos no pueden tener elementos repetidos, como vimos en los últimos artículos.

Esta manera de crear un frozenset a través de su constructor también es válida para el tipo set.

>>> c4 = set('la casa de la pradera')
>>> c4
{'a', ' ', 'c', 'e', 'd', 'l', 'p', 's', 'r'}

Una forma muy rápida de crear un conjunto a partir de un string, como podemos ver.

Set y frozenset son hermanos, por lo que puedes emplear muchos de los operadores y métodos que ya aprediste con set. Realizemos, por ejemplo, una unión:

>>> c1 = frozenset({1, 2, 3})
>>> c2 = frozenset({4, 5, 6})
>>> c1 | c2
frozenset({1, 2, 3, 4, 5, 6})

En cambio, ya que los frozenset son inmutables y no podemos modificarlos, no aceptan aquellos métodos que traten de alterar su composición. Intentemos agregar un nuevo elemento a c1 y veamos qué sucede:

>>> c1.add(5)
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    c1.add(5)
AttributeError: 'frozenset' object has no attribute 'add'

El mensaje es rotundo: el objeto frozenset no tiene método add.

¿Por qué usar un frozenset en lugar de un set? Una razón importante puede ser para garantizar que nuestro código no alterará una estructura de datos que no debamos modificar. Además, como veremos en breve cuando comencemos con los diccionarios, las claves de estos han de ser de un tipo inmutable, como son los strings, tuplas o frozensets, pero no servirían ni las listas ni los sets, que son modificables.

El tema de la mutabilidad en Python puede resultar un tanto misterioso si estás habituado a otros lenguajes de programación. Merecerá que se le dedique un artículo monográfico…

Javier Montero Gabarró


Python: Conjuntos inmutables con frozenset


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Deja un comentario

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies