Skip to content

    Chapter 21, Basic

    Dictionaries

    The dictionary associates keys with values and is the most powerful structure in the language. It appears everywhere, from configurations to API responses.

    Code for this chapter: basico/cap21_dicionarios.py

    Keys and values

    A dictionary stores pairs chave: valor. Since Python 3.7, it preserves the order of insertion. Keys need to be hashable (strings, numbers, tuples) and unique:

    basico/cap21_dicionarios.pylinhas 10 a 15
    pessoa = {"nome": "Ana", "idade": 30}
    print(pessoa["nome"])
    pessoa["cidade"] = "Recife"
    pessoa["idade"] = 31
    del pessoa["nome"]
    print(pessoa)
    
    Output
    Ana
    {'idade': 31, 'cidade': 'Recife'}
    

    Access safely

    Reading a key that does not exist raises KeyError. The method get returns a default value instead, and the operator in checks if the key exists:

    basico/cap21_dicionarios.pylinhas 20 a 26
    try:
        pessoa["email"]
    except KeyError as erro:
        print("KeyError:", erro)
    print(pessoa.get("email"))
    print(pessoa.get("email", "sem email"))
    print("idade" in pessoa)
    
    Output
    KeyError: 'email'
    None
    sem email
    True
    

    Iterate and modify

    basico/cap21_dicionarios.pylinhas 31 a 39
    estoque = {"maçã": 10, "pera": 0, "uva": 25}
    for fruta, quantidade in estoque.items():
        print(f"{fruta}: {quantidade}")
    print(list(estoque.keys()))
    print(list(estoque.values()))
    estoque.update({"pera": 5, "kiwi": 3})
    print(estoque.pop("kiwi"))
    print(estoque.setdefault("manga", 0))
    print(estoque)
    
    Output
    maçã: 10
    pera: 0
    uva: 25
    ['maçã', 'pera', 'uva']
    [10, 0, 25]
    3
    0
    {'maçã': 10, 'pera': 5, 'uva': 25, 'manga': 0}
    

    To merge two dictionaries, the operator | (Python 3.9 or higher) and unpacking with ** yield the same result, and in case of a repeated key, the one on the right wins:

    basico/cap21_dicionarios.pylinhas 41 a 44
    a = {"x": 1, "y": 2}
    b = {"y": 20, "z": 30}
    print(a | b)
    print({**a, **b})
    
    Output
    {'x': 1, 'y': 20, 'z': 30}
    {'x': 1, 'y': 20, 'z': 30}
    

    Count and group

    Counting occurrences is one of the most common tasks. The manual version uses get. The standard library has ready-made tools, Counter and defaultdict:

    basico/cap21_dicionarios.pylinhas 49 a 64
    from collections import Counter, defaultdict
    
    palavras = ["a", "b", "a", "c", "b", "a"]
    
    contagem = {}
    for palavra in palavras:
        contagem[palavra] = contagem.get(palavra, 0) + 1
    print(contagem)
    
    print(Counter(palavras))
    print(Counter(palavras).most_common(1))
    
    por_inicial = defaultdict(list)
    for nome in ["Ana", "Alice", "Bia", "Caio", "Beto"]:
        por_inicial[nome[0]].append(nome)
    print(dict(por_inicial))
    
    Output
    {'a': 3, 'b': 2, 'c': 1}
    Counter({'a': 3, 'b': 2, 'c': 1})
    [('a', 3)]
    {'A': ['Ana', 'Alice'], 'B': ['Bia', 'Beto'], 'C': ['Caio']}
    

    Nested data

    Dictionaries and lists combine freely. This is how data from a JSON API arrives:

    basico/cap21_dicionarios.pylinhas 69 a 79
    pedido = {
        "cliente": "Ana",
        "itens": [
            {"produto": "caneta", "qtd": 2},
            {"produto": "caderno", "qtd": 1},
        ],
    }
    total_itens = 0
    for item in pedido["itens"]:
        total_itens += item["qtd"]
    print(total_itens)
    
    Output
    3
    

    Exercise 1

    Frequency of each element

    Write frequencia(itens) that returns a dictionary with the count of each item, without using Counter.

    Exercise 2

    Sum dictionaries

    Write somar_dicts(d1, d2) that merges the two by summing the values of common keys. For {"a": 5, "b": 3} and {"b": 4, "c": 2}, the result is {"a": 5, "b": 7, "c": 2}.