Skip to content

    Chapter 20, Basic

    Tuples and sets

    The tuple is the list that does not change. The set is the collection that does not repeat. Each one solves a problem that the list solves poorly.

    Code for this chapter: basico/cap20_tuplas_conjuntos.py

    Tuples

    A tuple is a sequence immutable. Use it for data that forms a fixed record (coordinates, pairs of values, function returns):

    basico/cap20_tuplas_conjuntos.pylinhas 10 a 15
    dias = ("seg", "ter", "qua")
    print(dias[0], len(dias))
    try:
        dias[0] = "dom"
    except TypeError as erro:
        print(erro)
    
    Output
    seg 3
    'tuple' object does not support item assignment
    

    A syntax trick: what forms the tuple is the comma, not the parenthesis. A tuple with one element needs the final comma:

    basico/cap20_tuplas_conjuntos.pylinhas 17 a 19
    um = (1,)
    nao_tupla = (1)
    print(type(um), type(nao_tupla))
    
    Output
    <class 'tuple'> <class 'int'>
    

    Unpacking is where the tuple appears the most. The * captures "the rest" in a list:

    basico/cap20_tuplas_conjuntos.pylinhas 21 a 25
    ponto = (3, 4)
    x, y = ponto
    primeiro, *resto = [10, 20, 30, 40]
    print(x, y)
    print(primeiro, resto)
    
    Output
    3 4
    10 [20, 30, 40]
    

    When you want a tuple with names in the fields, use namedtuple:

    basico/cap20_tuplas_conjuntos.pylinhas 27 a 31
    from collections import namedtuple
    
    Ponto = namedtuple("Ponto", ["x", "y"])
    p = Ponto(3, 4)
    print(p, p.x + p.y)
    
    Output
    Ponto(x=3, y=4) 7
    

    The immutability of the tuple is shallow: it ensures that the items are not swapped, but if an item is mutable, it can still change:

    basico/cap20_tuplas_conjuntos.pylinhas 33 a 35
    registro = ("ana", [1, 2])
    registro[1].append(3)
    print(registro)
    
    Output
    ('ana', [1, 2, 3])
    

    Sets

    A set holds uniqueitems, with no guaranteed order, and answers "is this item here?" in practically constant time. The operations follow set theory:

    basico/cap20_tuplas_conjuntos.pylinhas 40 a 47
    s = {1, 2, 2, 3, 3, 3}
    print(s, len(s))
    vazio = set()
    print(type({}), type(vazio))
    a = {1, 2, 3, 4}
    b = {3, 4, 5, 6}
    print(a | b, a & b, a - b, a ^ b)
    print(3 in a)
    
    Output
    {1, 2, 3} 3
    <class 'dict'> <class 'set'>
    {1, 2, 3, 4, 5, 6} {3, 4} {1, 2} {1, 2, 5, 6}
    True
    

    {} creates a dictionary empty, not a set. For an empty set, use set().

    The items in a set need to be hashable, which in practice means immutable. A list cannot be included, but a tuple can. The frozenset is the immutable version of the set:

    basico/cap20_tuplas_conjuntos.pylinhas 49 a 55
    try:
        {[1, 2]}
    except TypeError as erro:
        print(erro)
    
    congelado = frozenset([1, 2])
    print(congelado)
    
    Output
    unhashable type: 'list'
    frozenset({1, 2})
    

    The order of a set is not guaranteed

    A set has no position, so there is no s[0]. The order in which it prints may change between executions, especially with strings. If you need order, use sorted(conjunto).

    Which structure to use

    I need...Use
    Items in order that can changelist
    A fixed record, or a composite keytuple
    Remove duplicates and test membership quicklyset
    Associate values with keysdict (next chapter)

    Exercise 1

    Remove duplicates while preserving order

    Write sem_duplicados(itens). For [3, 1, 3, 2, 1] the result is [3, 1, 2].

    Exercise 2

    Common items

    Write em_comum(a, b) that returns, sorted, the items present in both lists.