Percursos
/
Python
Python
/
Programa
/
Métodos de dicionário
Mé

Métodos de dicionário em Python

2 exercícios

Sobre Métodos de dicionário

A classe dict em Python disponibiliza muitos métodos úteis para trabalhar com dicionários. Alguns foram apresentados no conceito sobre dicts. Aqui vamos abordar mais alguns, juntamente com algumas técnicas para iterar e manipular dicionários.

  • <dict>.setdefault() adiciona chaves automaticamente sem lançar um KeyError.
  • <dict>.fromkeys(<iterable>, <default value>) cria um novo dict a partir de qualquer número de iteráveis.
  • <dict>.keys(), <dict>.values() e <dict>.items() fornecem iteradores convenientes.
  • sorted(<dict>.items()) permite reordenar facilmente as entradas de um dict.
  • <dict_one>.update(<dict_two>) atualiza um dict com os valores sobrepostos de outro dict.
  • <dict> | <other_dict> e <dict> |= <other_dict> fundem ou atualizam dois dicts através de operadores.
  • reversed(<dict>.keys()), reversed(<dict>.values()) ou reversed(<dict>.items()) produzem vistas invertidas.
  • <dict>.popitem() remove e devolve um par key, value.

setdefault() para inserções sem erros

O conceito sobre dicionários abordou anteriormente que <dict>.get(<key>, <default value>) devolve um value existente ou o default value se uma key não for encontrada no dicionário, evitando assim um KeyError. Isto funciona bem em situações em que preferes não ter tratamento de erros adicional, mas não podes confiar que a key que procuras esteja presente.

Para uma operação de inserção igualmente "segura" (sem KeyError), existe o método <dict>.setdefault(<key>, <default value>). O <dict>.setdefault(<key>, <default value>) devolve o value se a key existir no dicionário. Se a key não for encontrada, insere o par (key, default value) e devolve o default value para utilização.

>>> 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 preencher um dicionário a partir de um iterável

Para preencher rapidamente um dicionário com várias keys e valores predefinidos, o método de classe fromkeys(<iterable>, <default value>) itera por um iterável de keys e cria um novo dict. Todos os values serão definidos com o default value fornecido:

>>> 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'}

Remover e devolver um par (key, value) com .popitem()

O .popitem() remove e devolve um único par (key, value) de um dicionário. Os pares são devolvidos pela ordem Last-in-First-out (LIFO). Se o dicionário estiver vazio, chamar popitem() provoca um 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'

Iterar sobre as entradas de um dicionário através de vistas

Os métodos .keys(), .values() e .items() devolvem vistas iteráveis de um dicionário.

Estas vistas permitem percorrer facilmente as entradas sem as alterar. As vistas são também dinâmicas: quando os dados subjacentes do dicionário mudam, o view object associado reflete essa mudança:

>>> 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')])

Mais sobre .keys(), .values() e .items()

No Python 3.7+, os dicts preservam a ordem pela qual as entradas são inseridas, permitindo uma iteração First-in, First-out (FIFO) ao usar .keys(), .values() ou .items().

No Python 3.8+, as vistas são também reversíveis. Isto permite iterar keys, values ou pares (key, value) pela ordem Last-in, First-out (LIFO) com reversed(<dict>.keys()), reversed(<dict>.values()) ou 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')

Combinar dicionários com .update()

O <dict_one>.update(<dict_two>) pode ser usado para combinar dois dicionários. Este método pega nos pares (key,value) de <dict_two> e escreve-os em <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'}

Quando as chaves dos dois dicionários se sobrepõem, o value em dict_one é substituído pelo value correspondente 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'}

Fundir ou atualizar dicionários com os operadores de união (| e |=)

O Python 3.9 introduz uma forma diferente de fundir dicts: os operadores union. dict_one | dict_two cria um novo dicionário, constituído pelos pares (key, value) de dict_one e dict_two. Quando os dois dicionários partilham chaves, os valores de dict_two têm precedência.

>>> 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 comporta-se de forma semelhante a <dict_one>.update(<other>), mas, neste caso, other pode ser um dict ou um iterável 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'}

Ordenar um dicionário

Os dicionários não têm um método de ordenação incorporado. No entanto, é possível ordenar uma vista de dict com a função incorporada sorted() aplicada a .items(). A vista ordenada pode depois ser usada para criar um novo dicionário. A menos que se especifique uma chave de ordenação, a ordenação predefinida é feita sobre as keys do dicionário.

# 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'} 

Transpor chaves e valores de um dicionário

Trocar chaves e valores de forma fiável num dicionário dá algum trabalho, mas pode ser feito com um loop usando dict.items() ou numa compreensão de dicionário. Uma troca segura pressupõe que tanto as chaves como os valores do dict sejam 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'}

Se os valores guardados no dict não forem únicos, tornam-se necessárias verificações extra antes de se poder trocar chaves e 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 uma explicação detalhada sobre dicionários e métodos para trabalhar com eles, o tutorial oficial e a referência oficial da biblioteca são excelentes pontos de partida.

O Real Python e o Finxter também têm artigos bastante completos sobre dicionários em Python.

Para mais informações sobre ordenação, consulta o Sorting HOW TO na documentação do Python.

Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Métodos de dicionário

A prática está bloqueada

Desbloqueia mais 3 exercícios para praticares Métodos de dicionário