Tu

Tuplas em Python

15 exercícios

Sobre Tuplas

Um tuple é uma coleção imutável de itens em sequência.

Como a maioria das coleções (vê os tipos incorporados list, dict e set), os tuples podem conter qualquer tipo de dados (ou vários), incluindo outros tuples. Os elementos de um tuple podem ser iterados com a construção for item in <tuple>. Se precisares tanto do índice como do valor do elemento, podes usar for index, item in enumerate(<tuple>).

Como em qualquer sequência, podes aceder aos elementos de um tuple com a notação de parênteses retos, usando um número 0-based index a partir da esquerda ou um número -1-based index a partir da direita. Os tuples podem ser copiados na totalidade ou em parte com a notação de fatias ou <tuple>.copy(), e suportam todas as operações comuns de sequências. Por serem imutáveis, os tuples não suportam as operações de sequências mutáveis.

Os tuples ocupam muito pouco espaço de memória em comparação com outros tipos de coleção e têm tempo de acesso constante (O(1)) quando se usa um índice. No entanto, não podem ser redimensionados, ordenados ou alterados depois de criados, pelo que são menos flexíveis quando são precisas alterações ou atualizações frequentes aos dados. Se forem precisas atualizações ou expansões frequentes, um list, um collections.deque ou um array.array podem ser uma estrutura de dados mais adequada.


Construção de tuples

Os tuples podem ser criados de várias formas, usando o construtor da classe tuple ou a declaração (<element_1>, <element_2>) (literal de tuple).

Usar o construtor tuple() vazio ou com um iterável:

>>> no_elements = tuple()
()

# The constructor *requires* an iterable, so single elements must be passed in a list or another tuple.
>>> one_element = tuple([16])
(16,)

As strings são iteráveis, por isso usar um único str como argumento do construtor tuple() pode dar resultados surpreendentes:

# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')

Outros iteráveis também têm os seus elementos adicionados um a um:

>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)

>>> multiple_elements_set = tuple({2, 3, 5, 7, 11})
(2,3,5,7,11)

A iteração predefinida de um dict é feita sobre as chaves. Para incluir tanto as chaves como os valores num tuple criado a partir de um dicionário, usa <dict>.items(), que devolve um iterador de tuples (key, value).

>>> source_data = {"fish": "gold", "monkey": "brown"}

>>> multiple_elements_dict_1 = tuple(source_data)
('fish', 'monkey')

>>> multiple_elements_dict_2 = tuple(source_data.items())
(('fish', 'gold'), ('monkey', 'brown'))
Declarar um tuple como literal:

Como o construtor tuple() só aceita iteráveis (ou nada) como argumentos, é muito mais fácil criar um tuple de um só elemento através do método literal.

>>> no_elements = ()
()

>>> one_element = ("Guava",)
("Guava",)

Repara que, em geral, os parênteses não são obrigatórios para criar um tuple literal, apenas as vírgulas. No entanto, usar (<element_1>, <element_2>) é considerado mais legível na maioria das situações. Os parênteses também são obrigatórios em casos de ambiguidade, como um tuple vazio ou com um só elemento, ou quando uma função recebe um tuple como argumento.

>>> elements_separated_with_commas = "Parrot", "Bird", 334782
("Parrot", "Bird", 334782)

>>> elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60)
("Triangle", 60, 60, 60)

Outras estruturas de dados podem ser incluídas como elementos de um tuple, incluindo outros tuples.

>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))

>>> nested_data_structures_1 = (["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
(["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))

Os tuples podem ser concatenados com o operador mais +, que desempacota cada tuple e cria um novo tuple combinado.

>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby")
("George", 5, "cat", "Tabby")

#likewise, using the multiplication operator * is the equivalent of using + n times
>>> first_group = ("cat", "dog", "elephant")

>>> multiplied_group = first_group * 3
('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant')

Aceder aos dados

Podes aceder aos elementos dentro de um tuple (tal como nos outros tipos de sequência str e list) com a notação de parênteses retos. Os índices podem ir da left --> right (a começar em zero) ou da right --> left (a começar em -1). Os tuples também podem ser copiados na totalidade ou em parte com a notação de fatias ou com <tuple>.copy().

>>> student_info = ("Alyssa", "grade 3", "female", 8)

#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa

>>> student_name = student_info[-4]
Alyssa

#age is at index 3 or index -1
>>> student_age_1 = student_info[3]
8

>>> student_age_2 = student_info[-1]
8

Iteração sobre os elementos

Podes iterar sobre os elementos dentro de um tuple num ciclo com a sintaxe for item in <tuple>. Se precisares tanto dos índices como dos valores, podes usar for index, item in enumerate(<tuple>).

>>> student_info = ("Alyssa", "grade 3", "female", 8)
>>> for item in student_info:
...   print(item)
...
Alyssa
grade 3
female
8

>>> for index, item in enumerate(student_info):
...  print("Index is: " + str(index) + ", value is: " + str(item) + ".")
...
Index is: 0, value is: Alyssa.
Index is: 1, value is: grade 3.
Index is: 2, value is: female.
Index is: 3, value is: 8.

Tuples como informação homogénea

Os tuples são frequentemente usados como registos que contêm dados homogéneos do ponto de vista organizacional ou conceptual e tratados como uma única unidade de informação, mesmo que os elementos individuais sejam de tipos de dados heterogéneos.

>>> student_info = ("Alyssa", "grade 3", "female", 8)

Os tuples também são usados quando são precisas sequências de dados homogéneas e imutáveis para a hashability, para armazenamento num set ou para a criação de chaves num dicionário.

Repara que, embora os tuples sejam na maioria dos casos imutáveis, como podem conter qualquer estrutura de dados ou objeto, podem tornar-se mutáveis se algum dos seus elementos for um tipo mutável. Usar um tipo de dados mutável dentro de um tuple torna o tuple que o contém não utilizável como hash.

>>> cmyk_color_map = {
        (.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292),
        (0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01),
        (.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E),
        (0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C)
    }

>>> unique_rgb_colors = {
        (59, 178, 146),
        (247, 127, 1),
        (89, 16, 142),
        (140, 0, 76),
        (76, 0, 140)
     }

>>> teal_700 = hash((59, 178, 146))

>>> teal_700 = hash(("Pantone 228", [(140, 0, 76), 0x8C004C]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Tuples estendidos e tipos de dados relacionados

Os tuples são frequentemente usados como registos, mas só se pode aceder aos dados que contêm através da posição/índice. A classe namedtuple() do módulo collections amplia a funcionalidade básica dos tuples para permitir o acesso aos elementos por nome. Além disso, podes adaptar uma dataclass para oferecer uma funcionalidade semelhante de atributos com nome, com alguns prós e contras.

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

Aprende Tuplas

A prática está bloqueada

Desbloqueia mais 5 exercícios para praticares Tuplas