¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Python 3
  3. Diccionarios y algoritmos aplicados
Extrait - Python 3 Los fundamentos del lenguaje (4ª edición)
Extractos del libro
Python 3 Los fundamentos del lenguaje (4ª edición) Volver a la página de compra del libro

Diccionarios y algoritmos aplicados

Presentación

1. Definición

Un diccionario es una colección no ordenada de relaciones entre claves y valores. La semántica de Python 3.x aproxima la notación de los conjuntos a la de los diccionarios; existen efectivamente similitudes entre ambas colecciones, empezando por el hecho de que una clave de un diccionario debe poderse hashear.

Veamos la lista de métodos de un diccionario:

>>> dir(dict) 
['__class__', '__contains__', '__delattr__', '__delitem__', 
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', 
'__getitem__', '__gt__', '__hash__', '__init__', '__iter__', 
'__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', 
'__reduce_ex__', '__repr__', '__setattr__', '__setitem__', 
'__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 
'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 
'setdefault', 'update', 'values'] 

Los métodos que posee una lista y no posee un diccionario son:

>>> sorted(set(dir(list))-set(dir(dict))) 
['__add__', '__iadd__', '__imul__', '__mul__', '__reversed__', 
'__rmul__', 'append', 'count', 'extend', 'index', 'insert', 
'remove', 'reverse', 'sort'] 

En efecto, el diccionario no implementa más operadores que los de comparación. No existe ninguna noción de índices, aunque posee claves que son únicas, y no existe una relación de orden. No existe, tampoco, la noción de tramos, pues si bien es posible crearlos a partir de índices, no lo es a partir de claves.

>>> (sorted(set(dir(dict))-set(dir(list))) 
['clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'popitem', 
'setdefault', 'update', 'values'] 

Dado que no existen más operadores, son los métodos keys los que permiten obtener la lista...

Manipular un diccionario

1. Recuperar un valor de un diccionario

Es bastante sencillo saber si una clave está presente en un diccionario:

>>> 1 in d.keys() 
True 
>>> 5 in d.keys() 
False 

Tal y como se ha expuesto en la presentación del diccionario, la noción de índice no existe y es preciso trabajar con claves. Por ello, no existe la noción de tramos:

>>> d = {1: 1, 2: '2'} 
>>> d[1] 
1  
>>> d[1]=3  
>>> d[1:2]  
Traceback (most recent call last):  
File "<stdin>", line 1, in <module>  
TypeError: unhashable type  
>>> del d[1]  
>>> d  
{2: '2'} 

En el caso de que una clave no exista cuando se intenta acceder utilizando el operador corchete, se produce una excepción:

>>> d[5] 
Traceback (most recent call last): 
File "<stdin>", line 1, in <module> 
KeyError: 5 

Si no se quiere obtener una excepción, existe un método get que devuelve None si la clave no existe:

>>> d.get(5) 

También es posible devolver un valor por defecto en lugar de None.

>>> d.get(5, 'no') 
'no' 

Preste atención: el hecho de recuperar el valor por defecto (o None si no se precisa un valor alternativo) utilizando get no permite deducir la no existencia de la clave, puesto que el valor por defecto puede, a su vez, estar asociado a la clave.

El diccionario es, por tanto, un tipo esencial que funciona como un agregador de datos. Podemos considerar un diccionario como un espacio de nombres donde las claves serían los nombres de las variables. Los atributos de una clase se encapsulan mediante este tipo.

2. Modificar los valores de un diccionario

Un diccionario puede modificarse directamente utilizando la clave para modificar...

Uso avanzado de diccionarios

1. Agregar una relación de orden

Python 3.x y Python 2.7 disponen de un diccionario dotado de una relación de orden. Esto permite recorrer los elementos en un orden determinado.

>>> from collections import OrderedDict 
>>> d = OrderedDict() 
>>> d  
OrderedDict()  
>>> d[1]='1'  
>>> d[4]='4'  
>>> d[3]='3'  
>>> d[2]='2'  
>>> d  
OrderedDict([(1, '1'), (4, '4'), (3, '3'), (2, '2')]) 

Se aprecia claramente que el orden en que se presentan las tuplas clave-valor es el orden en que se han insertado.

A título de ejercicio de algorítmica, puede resultar útil construir un objeto que permita gestionar nuestra propia relación de orden. En nuestro caso, queremos que las claves queden clasificadas en todo momento:

class orderedDict(dict): 
   def items(self): 
          return sorted(super().items()) 
  
def keys(self): 
          return sorted(super().keys()) 
   def values(self): 
          return [self[k] for k in sorted(super().keys())] 
 
   def popitem(self): 
      try: 
          key = list(self.keys())[-1] 
      except IndexError: 
          raise KeyError('dictionary is empty') 
      value = self[key] 
      del self[key] 
      return (key, value) 

Podríamos destacar que es realmente práctico heredar directamente de dict, como se hace habitualmente en la práctica, y también es posible heredar de collections.UserDict, que puede presentar algunas ventajas, de manera similar a UserList para list.

2. Algorítmicas clásicas

Un diccionario es un objeto que debe verse como una lista de asociaciones entre claves y valores, donde las claves son, obligatoriamente, únicas y los valores pueden recibir cualquier valor.

Es posible trabajar únicamente sobre las claves o sobre...