Uma list é uma coleção mutável de itens em sequência.
Tal como a maioria das coleções (ver os tipos incorporados tuple, dict e set), as listas podem conter referências a qualquer tipo de dados (ou a vários), incluindo outras listas.
Tal como qualquer sequência, podes aceder aos itens através de um número de 0-based index a partir da esquerda e de -1-based index a partir da direita.
As listas podem ser copiadas na totalidade ou em parte através de notação de fatias ou de <list>.copy().
As listas suportam operações de sequência comuns e mutáveis, tais como min()/max(), <list>.index(), <list>.append() e <list>.reverse().
Os elementos de uma lista podem ser percorridos com a construção for item in <list>.
Podes usar for index, item in enumerate(<list>) quando precisas tanto do índice como do valor do elemento.
Nos bastidores, as lists são implementadas como arrays dinâmicos, semelhantes ao tipo ArrayList do Java, e são usadas sobretudo para guardar grupos de dados semelhantes (strings, números, sets, etc.) de comprimento desconhecido.
As listas são uma estrutura de dados extremamente flexível e útil, e muitos métodos e operações incorporados no Python produzem listas como resultado.
Uma list pode ser declarada como um literal com parênteses retos [] e vírgulas entre os elementos:
>>> no_elements = []
>>> no_elements
[]
>>> one_element = ["Guava"]
>>> one_element
['Guava']
>>> elements_separated_with_commas = ["Parrot", "Bird", 334782]
>>> elements_separated_with_commas
['Parrot', 'Bird', 334782]
Para maior legibilidade, podes usar quebras de linha quando há muitos elementos ou estruturas de dados aninhadas dentro de uma list:
>>> lots_of_entries = [
"Rose",
"Sunflower",
"Poppy",
"Pansy",
"Tulip",
"Fuchsia",
"Cyclamen",
"Lavender"
]
>>> lots_of_entries
['Rose', 'Sunflower', 'Poppy', 'Pansy', 'Tulip', 'Fuchsia', 'Cyclamen', 'Lavender']
# Each data structure is on its own line to help clarify what they are.
>>> nested_data_structures = [
{"fish": "gold", "monkey": "brown", "parrot": "grey"},
("fish", "mammal", "bird"),
['water', 'jungle', 'sky']
]
>>> nested_data_structures
[{'fish': 'gold', 'monkey': 'brown', 'parrot': 'grey'}, ('fish', 'mammal', 'bird'), ['water', 'jungle', 'sky']]
O construtor list() pode ser usado sem argumentos ou com um iterável como argumento.
O construtor percorre os elementos do iterável e adiciona-os à list pela ordem em que aparecem:
>>> no_elements = list()
>>> no_elements
[]
# The tuple is unpacked and each element is added.
>>> multiple_elements_from_tuple = list(("Parrot", "Bird", 334782))
>>> multiple_elements_from_tuple
['Parrot', 'Bird', 334782]
# The set is unpacked and each element is added.
>>> multiple_elements_from_set = list({2, 3, 5, 7, 11})
>>> multiple_elements_from_set
[2, 3, 5, 7, 11]
Os resultados de usar o construtor list com uma string ou um dict podem ser surpreendentes:
# String elements (Unicode code points) are iterated through and added *individually*.
>>> multiple_elements_string = list("Timbuktu")
>>> multiple_elements_string
['T', 'i', 'm', 'b', 'u', 'k', 't', 'u']
# Unicode separators and positioning code points are also added *individually*.
>>> multiple_code_points_string = list('अभ्यास')
>>> multiple_code_points_string
['अ', 'भ', '्', 'य', 'ा', 'स']
# The iteration default for dictionaries is over the keys, so only key data is inserted into the list.
>>> source_data = {"fish": "gold", "monkey": "brown"}
>>> multiple_elements_dict_1 = list(source_data)
['fish', 'monkey']
Como o construtor list só aceita iteráveis (ou nada) como argumentos, os objetos que não são iteráveis provocam um erro de tipo.
Por isso, é muito mais fácil criar uma list com um único item através do método literal.
# Numbers are not iterable, and so attempting to create a list with a number passed to the constructor fails.
>>> one_element = list(16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
# Tuples *are* iterable, so passing a one-element tuple to the constructor does work, but it's awkward
>>> one_element_from_iterable = list((16,))
>>> one_element_from_iterable
[16]
Podes aceder aos itens dentro das listas (bem como aos itens de outros tipos de sequência, str e tuple) através de 0-based index e de 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).
| índice a partir da esquerda ⟹ |
|
⟸ índice a partir da direita |
>>> breakfast_foods = ["Oatmeal", "Fruit Salad", "Eggs", "Toast"]
# Oatmeal is at index 0 or index -4.
>>> breakfast_foods[0]
'Oatmeal'
>>> breakfast_foods[-4]
'Oatmeal'
# Eggs are at index -2 or 2
>>> breakfast_foods[-2]
'Eggs'
>>> breakfast_foods[2]
'Eggs'
# Toast is at -1
>>> breakfast_foods[-1]
'Toast'
Podes aceder a uma secção dos elementos dentro de uma list através da notação de fatias (<list>[start:stop]).
Uma fatia é definida como uma sequência de elementos na posição index, tal que start <= index < stop.
O fatiamento devolve uma cópia dos itens "fatiados" e não modifica a list original.
Também podes usar um parâmetro step em [start:stop:step] para "saltar" ou filtrar os elementos da list (por exemplo, um step de 2 seleciona um elemento sim, outro não, dentro do intervalo):
>>> colors = ["Red", "Purple", "Green", "Yellow", "Orange", "Pink", "Blue", "Grey"]
# If there is no step parameter, the step is assumed to be 1.
>>> middle_colors = colors[2:6]
>>> middle_colors
['Green', 'Yellow', 'Orange', 'Pink']
# If the start or stop parameters are omitted, the slice will
# start at index zero, and will stop at the end of the list.
>>> primary_colors = colors[::3]
>>> primary_colors
['Red', 'Yellow', 'Blue']
Usar a função incorporada sum() numa lista devolve a soma de todos os números da lista:
>>> number_list = [1, 2, 3, 4]
>>> sum(number_list)
10
Também podes obter o comprimento de uma lista com a função len():
>>> long_list = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J"]
>>> len(long_list)
10
As listas também podem ser combinadas de várias formas:
# Using the plus + operator unpacks each list and creates a new list, but it is not efficient.
>>> new_via_concatenate = ["George", 5] + ["cat", "Tabby"]
>>> new_via_concatenate
['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
>>> multiplied_group
['cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant']
As listas fornecem um iterador e podem ser percorridas da mesma forma que outros tipos de sequência.
# Looping through the list and printing out each element.
>>> colors = ["Orange", "Green", "Grey", "Blue"]
>>> for item in colors:
... print(item)
...
Orange
Green
Grey
Blue
Para uma explicação mais aprofundada sobre loops e iterators, completa o conceito loops.
A Elyse está mesmo ansiosa por jogar um pouco de póquer (e outros jogos de cartas) durante a sua próxima viagem a Vegas. Como é uma grande fã de "auto-registo", quer criar algumas funções pequenas que a ajudem com tarefas de registo e pediu a tua ajuda para pensar nelas.
A Elyse gosta especialmente de póquer e quer acompanhar quantas rondas joga, e que rondas são essas. Cada ronda tem o seu próprio número, e cada mesa mostra o número da ronda que está a ser jogada. A Elyse escolhe uma mesa e senta-se para jogar a primeira ronda. Planeia jogar três rondas.
Implementa uma função get_rounds(<round_number>) que recebe o número da ronda atual e devolve uma única list com essa ronda e as duas seguintes que estão para vir:
>>> get_rounds(27)
[27, 28, 29]
A Elyse jogou algumas rondas na primeira mesa, depois fez uma pausa e jogou mais algumas rondas numa segunda mesa ... mas acabou com uma lista diferente para cada mesa! Quer juntar as duas listas, para poder acompanhar todas as rondas de póquer no mesmo sítio.
Implementa uma função concatenate_rounds(<rounds_1>, <rounds_2>) que recebe duas listas e devolve uma única list constituída por todas as rondas da primeira list, seguidas de todas as rondas da segunda list:
>>> concatenate_rounds([27, 28, 29], [35, 36])
[27, 28, 29, 35, 36]
Ao falar sobre algumas das rondas anteriores de póquer, outro jogador comenta como duas delas se desenrolaram de forma semelhante. A Elyse não tem a certeza se jogou essas rondas ou não.
Implementa uma função list_contains_round(<rounds>, <round_number>) que recebe dois argumentos, uma lista de rondas jogadas e um número de ronda. A função devolve True se a ronda estiver na lista de rondas jogadas, e False caso contrário:
>>> list_contains_round([27, 28, 29, 35, 36], 29)
True
>>> list_contains_round([27, 28, 29, 35, 36], 30)
False
A Elyse quer experimentar um novo jogo chamado Black Joe. É semelhante ao Black Jack (onde o objetivo é que as cartas na tua mão somem um valor alvo), mas no Black Joe o objetivo é que a média dos valores das cartas seja 7. A média pode ser calculada somando todos os valores das cartas e dividindo depois essa soma pelo número de cartas na mão.
Implementa uma função card_average(<hand>) que devolve o valor médio de uma mão de Black Joe.
>>> card_average([5, 6, 7])
6.0
No Black Joe, a rapidez é importante. A Elyse vai tentar encontrar uma forma mais rápida de calcular a média.
Pensou em duas formas de obter um número semelhante a uma média:
Implementa a função approx_average_is_average(<hand>), em que hand é uma lista com os valores das cartas na tua mão.
Devolve True se uma or ambas das estratégias acima referidas resultarem num número igual à média real.
Nota: O comprimento de todas as mãos é ímpar, para facilitar encontrar a mediana.
>>> approx_average_is_average([1, 2, 3])
True
>>> approx_average_is_average([2, 3, 4, 8, 8])
True
>>> approx_average_is_average([1, 2, 3, 5, 9])
False
Intrigada com os resultados da sua experiência com médias, a Elyse pergunta-se se calcular a média das cartas nas posições pares versus a média das cartas nas posições ímpares daria os mesmos resultados. Está na hora de outra função de teste!
Implementa uma função average_even_is_average_odd(<hand>) que devolve um Boolean a indicar se a média das cartas nos índices pares é igual à média das cartas nos índices ímpares.
>>> average_even_is_average_odd([1, 2, 3])
True
>>> average_even_is_average_odd([1, 2, 3, 4])
False
Cada 11.ª mão no Black Joe é uma mão bónus com uma regra bónus: se a última carta que tiras for um valete, duplicas o seu valor.
Implementa uma função maybe_double_last(<hand>) que recebe uma mão e verifica se a última carta é um valete (11). Se a última carta for um valete (11), duplica o seu valor antes de devolver a mão.
>>> hand = [5, 9, 11]
>>> maybe_double_last(hand)
[5, 9, 22]
>>> hand = [5, 9, 10]
>>> maybe_double_last(hand)
[5, 9, 10]
Inscreve-te no Exercism para aprenderes e dominares Python com 17 conceitos146 exercícios, e mentoria humana real, tudo grátis.