Trilhas
/
Python
Python
/
Exercícios
/
A montanha-russa colossal da Chaitana
A montanha-russa colossal da Chaitana

A montanha-russa colossal da Chaitana

Exercício de aprendizagem

Introdução

Uma list é uma coleção mutável de itens em sequência. Como a maioria das coleções (veja os tipos tuple, dict e set embutidos), as listas podem conter referências a qualquer tipo de dado, ou a vários deles, inclusive outras listas. As listas podem ser copiadas por inteiro ou em parte com a notação de fatia ou com <list>.copy(). Como qualquer sequência, os elementos dentro de lists são referenciados por um número 0-based index a partir da esquerda, ou por um número -1-based index a partir da direita.

As listas aceitam tanto operações de sequência comuns quanto operações de sequência mutáveis, como min(<list>)/max(<list>), <list>.index(), <list>.append() e <list>.reverse(). Os elementos dentro de uma list podem ser percorridos com a construção for item in <list>. Já for index, item in enumerate(<list>) pode ser usado quando você precisa tanto do índice quanto do valor do elemento.

O Python também oferece vários métodos de lista úteis para trabalhar com listas. Alguns desses list methods são apresentados abaixo.

Note que, quando você manipula uma list com um list-method, você altera o objeto de lista que foi passado. Se você não quiser modificar a list original, vai precisar pelo menos fazer uma shallow copy dela com uma fatia ou com <list>.copy().

Adicionando itens

Para adicionar um item ao final, ou ao "lado direito", de uma lista existente, use <list>.append(<item>):

>>> numbers = [1, 2, 3]
>>> numbers.append(9)

>>> numbers
[1, 2, 3, 9]

Em vez de apenas acrescentar, <list>.insert() permite adicionar o item a um índice específico da lista. Ele aceita 2 parâmetros:

  1. o <index> no qual você quer que o item seja inserido.
  2. o <item> a ser inserido.

Nota: Se o index informado for 0, o item será adicionado ao início ("lado esquerdo") da list. Se o index informado for maior que o último index da list, o item será adicionado na posição final, o equivalente a usar <list>.append(<item>).

>>> numbers = [1, 2, 3]
>>> numbers.insert(0, -2)

>>> numbers
[-2, 1, 2, 3]

>>> numbers.insert(1, 0)

>>> numbers
[-2, 0, 1, 2, 3]

<list>.extend(<item>) pode ser usado para combinar uma lista existente com os elementos de outro iterável (por exemplo, um set, tuple, str ou list). O iterável é desempacotado e os elementos são acrescentados em ordem (usar <list>.append(<item>) nessa situação adicionaria o iterável inteiro como um único item.)

>>> numbers = [1, 2, 3]
>>> other_numbers = [5, 6, 7]

>>> numbers.extend(other_numbers)

>>> numbers
[1, 2, 3, 5, 6, 7]

>>> numbers.extend([8, 9])

>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9]

>>> numbers.append([8,9])

>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9, [8, 9]]

Removendo itens

Para excluir um item de uma lista, use <list>.remove(<item>), passando como argumento o item a ser removido. <list>.remove(<item>) lançará um ValueError se o item não estiver presente na list.

>>> numbers = [1, 2, 3]
>>> numbers.remove(2)

>>> numbers
[1, 3]

# Trying to remove a value that is not in the list throws a ValueError
>>> numbers.remove(0)
ValueError: list.remove(x): x not in list

Como alternativa, usar o método <list>.pop(<index>) remove e return um elemento, deixando-o disponível para uso.

<list>.pop(<index>) aceita um parâmetro opcional: o index do item a ser removido e retornado. Se o argumento index (opcional) não for especificado, o último elemento da list será removido e retornado. Se o index especificado for maior que o index do último item, um IndexError é levantado.

>>> numbers = [1, 2, 3]

>>> numbers.pop(0)
1

>>> numbers
[2, 3]

>>> numbers.pop()
3

>>> numbers
[2]

>>> numbers.pop(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: pop index out of range

Todos os elementos podem ser removidos de uma list com list.clear(). Ele não aceita nenhum parâmetro.

>>> numbers = [1, 2, 3]
>>> numbers.clear()

>>> numbers
[]

Invertendo e reordenando

O método <list>.reverse() inverte a ordem dos elementos no próprio local.

>>> numbers = [1, 2, 3]
>>> numbers.reverse()

>>> numbers
[3, 2, 1]

Uma lista pode ser reordenada no próprio local com a ajuda de <list>.sort(). A ordem padrão de ordenação é crescente, a partir da esquerda. A documentação do Python traz dicas e técnicas adicionais de ordenação.

Note

De 2002 a 2022, o Python usou internamente um algoritmo chamado Timsort para organizar listas, mas passou a usar Powersort a partir do Python 3.11.

>>> names = ["Tony", "Natasha", "Thor", "Bruce"]

# The default sort order is *ascending*.
>>> names.sort()

>>> names
["Bruce", "Natasha", "Thor", "Tony"]

Se você quiser uma ordem decrescente, passe o argumento reverse=True:

>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> names.sort(reverse=True)

>>> names
["Tony", "Thor", "Natasha", "Bruce"]

Nos casos em que modificar a lista original não é desejável, a função embutida sorted(<iterable>) pode ser usada para retornar uma cópia ordenada.

>>> names = ["Tony", "Natasha", "Thor", "Bruce"]

>>> sorted(names)
['Bruce', 'Natasha', 'Thor', 'Tony']

Ocorrências de um item em uma lista

O número de ocorrências de um elemento em uma lista pode ser calculado com a ajuda de list.count(<item>). Ele recebe como argumento o item a ser contado e retorna o número total de vezes que esse elemento aparece na list.

>>> items = [1, 4, 7, 8, 2, 9, 2, 1, 1, 0, 4, 3]

>>> items.count(1)
3

Encontrando o índice dos itens

<list>.index(<item>) retorna o número do index da primeira ocorrência de um item passado. Se não houver nenhuma ocorrência, um ValueError é lançado. Se a posição exata de um item não for necessária, o operador in embutido é mais eficiente para verificar se uma lista contém um determinado valor.

A indexação começa em zero a partir da esquerda, então a posição do item "primeiro" é 0. A indexação também funciona a partir da direita, começando com -1.

>>> items = [7, 4, 1, 0, 2, 5]

>>> items.index(4)
1

>>> items.index(10)
ValueError: 10 is not in list

Os índices start e end também podem ser informados para restringir a busca a uma seção específica da list:

>>> names = ["Tina", "Leo", "Thomas", "Tina", "Emily", "Justin"]

>>> names.index("Tina")
0

>>> names.index("Tina", 2, 5)
3

Instruções

Chaitana é dona de um parque temático muito popular. Ela tem apenas uma atração, bem no centro de um terreno belamente paisagístico: a Maior Montanha-Russa do Mundo(TM). Embora só exista essa única atração, pessoas vêm de todas as partes do mundo e ficam horas na fila pela oportunidade de andar na hypercoaster de Chaitana.

Há duas filas para essa atração, cada uma representada como uma list:

  1. Fila Normal
  2. Fila Express (também conhecida como Fast-track), em que as pessoas pagam a mais por acesso prioritário.

Você recebeu a tarefa de escrever um código para gerenciar melhor os visitantes do parque. Você precisa implementar as funções a seguir o quanto antes, antes que os visitantes (e sua chefe, Chaitana!) fiquem de mau humor. Certifique-se de ler com atenção. Algumas tarefas pedem que você altere ou atualize a fila existente, enquanto outras pedem que você faça uma cópia dela.

1. Me adicione à fila

Defina a função add_me_to_the_queue() que recebe 4 parâmetros <express_queue>, <normal_queue>, <ticket_type>, <person_name> e retorna a fila apropriada atualizada com o nome da pessoa.

  1. <ticket_type> é um int em que 1 == express_queue e 0 == normal_queue.
  2. <person_name> é o nome (como str) da pessoa a ser adicionada à fila correspondente.
>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=1, person_name="RichieRich")
...
["Tony", "Bruce", "RichieRich"]

>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=0, person_name="HawkEye")
....
["RobotGuy", "WW", "HawkEye"]

2. Onde estão meus amigos?

Uma pessoa chegou atrasada ao parque, mas quer entrar na fila onde seus amigos estão esperando. Mas ela não tem ideia de onde seus amigos estão na fila e não há sinal de celular para ligar para eles.

Defina a função find_my_friend() que recebe 2 parâmetros queue e friend_name e retorna a posição na fila do nome da pessoa.

  1. <queue> é a list de pessoas na fila.
  2. <friend_name> é o nome do amigo cujo índice (lugar na fila) você precisa encontrar.

Lembre-se: a indexação começa em 0 pela esquerda e em -1 pela direita.

>>> find_my_friend(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], friend_name="Steve")
...
1

3. Posso entrar na fila com eles?

Agora que seus amigos foram encontrados (na tarefa nº 2 acima), a pessoa que chegou atrasada gostaria de se juntar a eles em seu lugar na fila. Defina a função add_me_with_my_friends() que recebe 3 parâmetros queue, index e person_name.

  1. <queue> é a list de pessoas na fila.
  2. <index> é a posição em que a nova pessoa deve ser adicionada.
  3. <person_name> é o nome da pessoa a adicionar na posição do índice.

Retorne a fila atualizada com o nome de quem chegou atrasado.

>>> add_me_with_my_friends(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], index=1, person_name="Bucky")
...
["Natasha", "Bucky", "Steve", "T'challa", "Wanda", "Rocket"]

4. Pessoa mal-educada na fila

Você acabou de ouvir na fila que há uma pessoa muito mal-educada empurrando, gritando e causando confusão. Você precisa expulsar essa pessoa por mau comportamento!

Defina a função remove_the_mean_person() que recebe 2 parâmetros queue e person_name.

  1. <queue> é a list de pessoas na fila.
  2. <person_name> é o nome da pessoa que precisa ser expulsa.

Retorne a fila atualizada sem o nome da pessoa mal-educada.

>>> remove_the_mean_person(queue=["Natasha", "Steve", "Eltran", "Wanda", "Rocket"], person_name="Eltran")
...
["Natasha", "Steve", "Wanda", "Rocket"]

5. Xarás

Talvez você nunca tenha visto duas pessoas sem parentesco que se parecem exatamente iguais, mas com certeza já viu pessoas sem parentesco com exatamente o mesmo nome (xarás)! Hoje, parece que há muitos deles presentes. Você quer saber quantas vezes um determinado nome aparece na fila.

Defina a função how_many_namefellows() que recebe 2 parâmetros queue e person_name.

  1. <queue> é a list de pessoas na fila.
  2. <person_name> é o nome que você acha que pode aparecer mais de uma vez na fila.

Retorne o número de ocorrências de person_name, como um int.

>>> how_many_namefellows(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"], person_name="Natasha")
...
2

6. Remova a última pessoa

Infelizmente, o parque está superlotado hoje e você precisa remover a última pessoa da fila normal (você vai dar a ela um voucher para voltar na fast-track em outro dia). Você terá que definir a função remove_the_last_person() que recebe 1 parâmetro queue, que é a lista de pessoas na fila.

Você deve atualizar a list e também return o nome da pessoa que foi removida, para poder escrever o voucher dela.

>>> remove_the_last_person(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
'Rocket'

7. Ordene a lista da fila

Por motivos administrativos, você precisa colocar todos os nomes de uma fila em ordem alfabética.

Defina a função sorted_names() que recebe 1 argumento, queue (a list de pessoas na fila), e retorna uma cópia sorted da list.

>>> sorted_names(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
['Eltran', 'Natasha', 'Natasha', 'Rocket', 'Steve']
Editar via GitHub O link abre em uma nova janela ou aba
Python Exercism

Tudo pronto para começar A montanha-russa colossal da Chaitana?

Crie sua conta no Exercism para aprender e dominar Python com 17 conceitos146 exercícios e mentoria humana de verdade, tudo de graça.