La clase dict de Python proporciona muchos métodos útiles para trabajar con diccionarios.
Algunos ya se presentaron en el concepto de dict.
Aquí veremos algunos más, junto con algunas técnicas para recorrer y manipular diccionarios.
<dict>.setdefault() añade claves automáticamente sin lanzar un KeyError.<dict>.fromkeys(<iterable>, <default value>) crea un nuevo dict a partir de cualquier número de iterables.<dict>.keys(), <dict>.values() y <dict>.items() proporcionan iteradores prácticos.sorted(<dict>.items()) permite reordenar fácilmente las entradas de un dict.<dict_one>.update(<dict_two>) actualiza un dict con los valores coincidentes de otro dict.<dict> | <other_dict> y <dict> |= <other_dict> fusionan o actualizan dos dict mediante operadores.reversed(<dict>.keys()), reversed(<dict>.values()) o reversed(<dict>.items()) producen vistas invertidas.<dict>.popitem() elimina y devuelve un par key, value.setdefault() para insertar sin erroresEn el concepto de diccionario ya vimos que <dict>.get(<key>, <default value>) devuelve un value existente o el default value si una key no se encuentra en el diccionario, evitando así un KeyError.
Esto funciona bien en situaciones en las que prefieres no añadir una gestión de errores adicional, pero no puedes confiar en que la key que buscas esté presente.
Para una operación de inserción igualmente «segura» (sin KeyError), existe el método <dict>.setdefault(<key>, <default value>).
<dict>.setdefault(<key>, <default value>) devolverá el value si la key se encuentra en el diccionario.
Si la clave no se encuentra, insertará el par (key, default value) y devolverá el default value para su uso.
>>> palette_I = {'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd'}
# Looking for the value associated with key "Rock Brown".The key does not exist,
# so it is added with the default value, and the value is returned.
>>> palette.setdefault('Rock Brown', '#694605')
'#694605'
# The (key, default value) pair has now been added to the dictionary.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Rock Brown': '#694605'}
fromkeys() para rellenar un diccionario a partir de un iterablePara rellenar rápidamente un diccionario con varias keys y valores predeterminados, el método de clase fromkeys(<iterable>, <default value>) recorre un iterable de keys y crea un nuevo dict.
Todos los values se establecerán al default value proporcionado:
>>> new_dict = dict.fromkeys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'], 'fill in hex color here')
{'Grassy Green': 'fill in hex color here',
'Purple Mountains Majesty': 'fill in hex color here',
'Misty Mountain Pink': 'fill in hex color here'}
.popitem()
.popitem() elimina y devuelve un único par (key, value) de un diccionario.
Los pares se devuelven en orden último en entrar, primero en salir (LIFO).
Si el diccionario está vacío, llamar a popitem() lanzará un KeyError:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_I.popitem()
('Misty Mountain Pink', '#f9c5bd')
>>> palette_I.popitem()
('Purple Mountains Majesty', '#8076a3')
>>> palette_I.popitem()
('Grassy Green', '#9bc400')
# All (key, value) pairs have been removed.
>>> palette_I.popitem()
Traceback (most recent call last):
line 1, in <module>
palette_I.popitem()
KeyError: 'popitem(): dictionary is empty'
Los métodos .keys(), .values() y .items() devuelven vistas iterables de un diccionario.
Estas vistas permiten recorrer las entradas fácilmente sin modificarlas.
Las vistas también son dinámicas: cuando cambian los datos subyacentes del diccionario, el view object asociado refleja el cambio:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
# Using .keys() returns a list of keys.
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink'])
# Using .values() returns a list of values.
>>> palette_I.values()
dict_values(['#9bc400', '#8076a3', '#f9c5bd'])
# Using .items() returns a list of (key, value) tuples.
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', '#8076a3'), ('Misty Mountain Pink', '#f9c5bd')])
# Views are dynamic. Changing values in the dict
# changes all of the associated views.
>>> palette_I['Purple Mountains Majesty'] = (128, 118, 163)
>>> palette_I['Deep Red'] = '#932432'
>>> palette_I.values()
dict_values(['#9bc400', (128, 118, 163), '#f9c5bd', '#932432'])
>>> palette_I.keys()
dict_keys(['Grassy Green', 'Purple Mountains Majesty', 'Misty Mountain Pink', 'Deep Red'])
>>> palette_I.items()
dict_items([('Grassy Green', '#9bc400'), ('Purple Mountains Majesty', (128, 118, 163)), ('Misty Mountain Pink', '#f9c5bd'), ('Deep Red', '#932432')])
.keys(), .values() y .items()
En Python 3.7+, los dicts conservan el orden en que se insertan las entradas, lo que permite iterar primero en entrar, primero en salir (FIFO) al usar .keys(), .values() o .items().
En Python 3.8+, las vistas también son reversibles.
Esto permite iterar claves, valores o pares (key, value) en orden último en entrar, primero en salir (LIFO) usando reversed(<dict>.keys()), reversed(<dict>.values()) o reversed(<dict>.items()):
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> for item in palette_II.items():
... print(item)
...
('Factory Stone Purple', '#7c677f')
('Green Treeline', '#478559')
('Purple baseline', '#161748')
>>> for item in reversed(palette_II.items()):
... print(item)
...
('Purple baseline', '#161748')
('Green Treeline', '#478559')
('Factory Stone Purple', '#7c677f')
.update()
<dict_one>.update(<dict_two>) se puede usar para combinar dos diccionarios.
Este método toma los pares (key, value) de <dict_two> y los escribe en <dict_one>:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple Baseline': '#161748'}
>>> palette_I.update(palette_II)
# Note that new items from palette_II are added.
>>> palette_I
{'Grassy Green': '#9bc400', 'Purple Mountains Majesty': '#8076a3', 'Misty Mountain Pink': '#f9c5bd', 'Factory Stone Purple': '#7c677f', 'Green Treeline': '#478559', 'Purple Baseline': '#161748'}
Cuando las claves de los dos diccionarios coinciden, el value de dict_one se sobrescribe con el value correspondiente de dict_two:
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> palette_III = {'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> palette_I.update(palette_III)
# Overlapping values in palette_I are replaced with
# values from palette_III
>>> palette_I
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559', 'Purple baseline': '#161748'}
| y |=)Python 3.9 introduce otra forma de fusionar dicts: los operadores union.
dict_one | dict_two crea un nuevo diccionario, formado por los pares (key, value) de dict_one y dict_two.
Cuando ambos diccionarios comparten claves, los valores de dict_two tienen prioridad.
>>> palette_I = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd'}
>>> palette_II = {'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
>>> new_dict = palette_I | palette_II
>>> new_dict
...
{'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
dict_one |= other se comporta de forma similar a <dict_one>.update(<other>), pero en este caso, other puede ser un dict o un iterable de pares (key, value):
>>> palette_III = {'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189)}
>>> new_dict |= palette_III
>>> new_dict
...
{'Grassy Green': (155, 196, 0),
'Purple Mountains Majesty': (128, 118, 163),
'Misty Mountain Pink': (249, 197, 189),
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
Los diccionarios no tienen un método de ordenación integrado.
Sin embargo, es posible ordenar una vista de dict usando la función integrada sorted() con .items().
La vista ordenada se puede usar entonces para crear un nuevo diccionario.
A menos que se especifique una clave de ordenación, la ordenación predeterminada se hace sobre las keys del diccionario.
# Default ordering for a dictionary is last in, first out (LIFO).
>>> color_palette = {'Grassy Green': '#9bc400',
'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
# The default sort order for a dictionary uses the keys.
>>> sorted_palette = dict(sorted(color_palette.items()))
>>> sorted_palette
{'Factory Stone Purple': '#7c677f',
'Grassy Green': '#9bc400',
'Green Treeline': '#478559',
'Misty Mountain Pink': '#f9c5bd',
'Purple Mountains Majesty': '#8076a3',
'Purple baseline': '#161748'}
# A sort key can be provided in the form
# of an anonymous function (lambda).
>>> value_sorted_palette = dict(sorted(color_palette.items(), key=lambda color: color[1]))
>>> value_sorted_palette
{'Purple baseline': '#161748',
'Green Treeline': '#478559',
'Factory Stone Purple': '#7c677f',
'Purple Mountains Majesty': '#8076a3',
'Grassy Green': '#9bc400',
'Misty Mountain Pink': '#f9c5bd'}
Intercambiar claves y valores de forma fiable en un diccionario requiere algo de trabajo, pero se puede conseguir con un loop que use dict.items() o con una comprensión de diccionario.
Un intercambio seguro supone que tanto las claves como los valores del dict son hashable.
color_reference = {'Purple Mountains Majesty': '#8076a3',
'Misty Mountain Pink': '#f9c5bd',
'Factory Stone Purple': '#7c677f',
'Green Treeline': '#478559',
'Purple baseline': '#161748'}
# Creating a new dictionary to hold the swapped entries.
>>> swapped_color_reference = {}
# Iterating through the dictionary, using values as keys.
>>> for key, value in color_reference.items():
... swapped_color_reference[value] = key
>>> swapped_color_reference
{'#8076a3': 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
'#478559': 'Green Treeline',
'#161748': 'Purple baseline'}
# A dictionary comprehension can also be used to swap entries.
>>> swapped = {value: key for key, value in
color_reference.items()}
>>> swapped
{'#8076a3': 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
'#478559': 'Green Treeline',
'#161748': 'Purple baseline'}
Si los valores almacenados en el dict no son únicos, hay que hacer comprobaciones adicionales antes de poder intercambiar claves y valores:
# Things become more complicated if there are duplicates in
# potential key values.This dict is arranged by hex, RGB, and HSL
# keys, but values repeat.
>>> extended_colors = {'#8076a3': 'Purple Mountains Majesty',
(128, 118, 163): 'Purple Mountains Majesty',
(21, 28, 0, 36): 'Purple Mountains Majesty',
'#f9c5bd': 'Misty Mountain Pink',
(249, 197, 189): 'Misty Mountain Pink',
(0, 21, 24, 2): 'Misty Mountain Pink',
'#7c677f': 'Factory Stone Purple',
(124, 103, 127): 'Factory Stone Purple',
(2, 19, 0, 50): 'Factory Stone Purple',
'#478559': 'Green Treeline',
(71, 133, 89): 'Green Treeline',
(47, 0, 33, 48): 'Green Treeline'}
# New empty dictionary for holding swapped entries.
>>> consolidated_colors = {}
# Iterating over (key, value) pairs using .items()
>>> for key, value in extended_color_reference.items():
... if value in consolidated_colors: # <--Check if key has already been created.
... consolidated_colors[value].append(key)
... else:
... consolidated_colors[value] = [key] # <--Create a value list with the former key in it.
>>> consolidated_colors
{'Purple Mountains Majesty': ['#8076a3', (128, 118, 163), (21, 28, 0, 36)],
'Misty Mountain Pink': ['#f9c5bd', (249, 197, 189), (0, 21, 24, 2)],
'Factory Stone Purple': ['#7c677f', (124, 103, 127), (2, 19, 0, 50)],
'Green Treeline': ['#478559', (71, 133, 89), (47, 0, 33, 48)]}
Para obtener una explicación detallada de los diccionarios y de los métodos para trabajar con ellos, el tutorial oficial y la referencia oficial de la biblioteca son excelentes puntos de partida.
Real Python y Finxter también tienen artículos muy completos sobre diccionarios de Python.
Para saber más sobre la ordenación, consulta el Sorting HOW TO en la documentación de Python.