Python Iluminado

Listas

img

Existem quatro tipos de dados de coleção na linguagem de programação Python, são eles:

  • Listas: Coleção ordenada e mutável. Permite membros duplicados.
  • Tuplas: Coleção ordenada e imutável. Permite membros duplicados.
  • Sets: Coleção não-ordenada e não-indexada. Não permite membros duplicados.
  • Dicionários: Coleção não-ordenada, mutável e indexável. Não permite membros duplicados.

Dos dados compostos, usados para agrupar outros valores, o mais versátil é a lista, que pode ser escrita como uma lista de valores separados por vírgula e entre colchetes. As listas podem conter itens de tipos diferentes, mas geralmente os itens possuem o mesmo tipo.

Fundamentos Básicos de Listas

Para melhor entendermos o conceito de Listas, vamos definir a nossa primeira lista que será chamada de L e irá conter as letras das palavras "Monty Python":

L = ['M','o','n','t','y',' ','P','y','t','h','o','n']

Veja que podemos imprimir o conteúdo da lista com o comando print():

print(L) # ['M', 'o', 'n', 't', 'y', ' ', 'P', 'y', 't', 'h', 'o', 'n']

Com o comando len() podemos verificar o tamanho (número de itens) da lista:

len(L) # 12

Podemos acessar apenas determinados itens da lista utilizando o conceito de slicing:

print(L[6:10]) # ['P', 'y', 't', 'h']
print(L[-12:-7]) # ['M', 'o', 'n', 't', 'y']

Observe esta lista que definimos é uma lista de caracteres, se quisermos uní-los para formar as palavras, podemos usar o método join() da seguinte forma:

nome = ''.join(L)
print(nome) # Monty Python

Acessando Elementos de uma Lista

Vamos agora definir mais três listas para entendermos melhor como elas funcionam:

ciencias = ['física', 'química', 'matemática']
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
hibrida = [1, 2.3, "Rafael"]

Semelhantes às strings, as listas também consideram o índice começando por 0, além disso, as listas podem ser manipuladas de várias formas, como concatenadas e sliced.

A notação específica para fazer o slicing das listas é:

lista[inicio:parada] # item de inicio até o item de parada - 1
lista[inicio:] # item de inicio até o fim da lista
lista[:parada] # itens do começo da lista até parada - 1
lista[:] # cópia da lista inteira

Existe também um valor de passo, que determina o número de passos para acessar os itens:

lista[inicio:parada:passo] # item de inicio até o item de parada - 1 em um determinado número de passos

A outra característica é que o início ou a parada podem ser um número negativo, o que significa que conta a partir do final da lista em vez do início. Para compreender este conceito melhor, vamos acessar os elementos de nossas listas de diversas maneiras.

Imprimindo do elemento de índice 0 até o elemento de índice 1:

print(ciencias[0:2]) # ['física', 'química']

Imprimindo apenas o elemento de índice 2:

print(numeros[2]) # 3

Imprimindo o último elemento da lista:

print(hibrida[-1]) # Rafael

Imprimindo a lista inteira:

print(ciencias[:]) # ['física', 'química', 'matemática']

Imprimindo até o elemento de índice 5:

print(numeros[:6]) # [1, 2, 3, 4, 5, 6]

Imprimindo do elemento de índice 2 adiante:

print(numeros[2:]) # [3, 4, 5, 6, 7, 8, 9, 10]

Podemos imprimir apenas os números ímpares da lista ao definirmos um valor de passo igual a 2, por exemplo:

print(numeros[0:10:2]) # [1, 3, 5, 7, 9]

A função slice() nos permite atingir a mesma funcionalidade que esta notação, vejamos alguns exemplos:

ciencias[slice(0,2)] # ['física', 'química']
numeros[slice(0,10,2)] # [1, 3, 5, 7, 9]

Alterando Elementos de uma Lista

A lista é um tipo de dados mutável. Assim que uma lista for criada:

  • Elementos podem ser modificados
  • Valores individuais podem ser substituídos
  • A ordem dos elementos pode ser alterada

Para compreendermos melhor as mutações de listas, vamos executar alterações em nossas listas.

Iniciaremos alterando o primeiro elemento da lista ciencias:

ciencias[0] = "computação"
print(ciencias[0]) # computação

Vamos agora incrementar mais ciências a nossa lista ciencias:

ciencias += ['astronomia','biologia']
print(ciencias) # ['computação', 'química', 'matemática', 'astronomia', 'biologia']

Acessando Itens de uma Lista

Uma outra maneira de acessarmos os itens de uma lista é usando um for loop:

for n in numeros: # Percorre cada elemento de numeros
print(n) # Imprime os elementos

Em breve veremos o for loop com mais detalhes.

Checando por Valores em uma Lista

Também podemos checar se um determinado valor existe em uma lista com o uso da palavra-chave in:

print("química" in ciencias) # True
print("cosmologia" in ciencias) # False

Adicionando Itens a uma Lista

Uma outra maneira de adicionarmos mais itens a uma lista é com o uso do método append(), por exemplo:

numeros.append(11)
print(numeros) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

Se você precisarmos anexar vários itens à mesma lista, o método extend() será útil. Precisamos simplesmente passar a lista de itens para anexar ao método extend, conforme o exemplo abaixo:

numeros.extend([12,13])
print(numeros) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

Podemos também usar o método insert() para inserirmos itens em uma posição específica:

hibrida.insert(0, "Gabriel")
print(hibrida) # ['Gabriel', 1, 2.3, 'Rafael']

Passamos como argumento o número 0 e a string "Gabriel", indicando que desejamos inserir essa string na primeira posição da lista.

Removendo Itens de uma Lista

Uma tarefa muito comum é a de remoção de itens de uma lista, podemos por exemplo:

  • Deletar um elemento em um índice específico com del(lista[indice])
  • Remover elementos no fim da lista com lista.pop(), retornará o elemento removido
  • Remover um elemento específico com lista.remove(elemento) - Busca pelo elemento e remove ele - Se o elemento ocorre múltiplas vezes na lista, remove a primeira ocorrência - Se o elemento não estiver presente na lista, ocorrerá um erro

Definiremos então uma nova lista para trabalharmos com essas operações de remoção:

lista = [2, 1, 3, 6, 3, 7, 0]
lista.remove(2) # Causa mutação em L = [1, 3, 6, 3, 7, 0]
lista.remove(3) # Causa mutação em L = [1, 6, 3, 7, 0]
del(lista[1]) # Causa mutação em L = [1, 3, 7, 0]
lista.pop() # retorna 0 e causa mutação em L = [1, 3, 7]

Vamos agora remover a ciência química de nossa lista ciencias:

ciencias.remove("química")
print(ciencias) # ['computação', 'matemática', 'astronomia', 'biologia']

Dessa vez, utilizando a palavra-chave del:

del ciencias[0]
print(ciencias) # ['matemática', 'astronomia', 'biologia']

Fique atento, pois caso não seja especificado um índice, del vai eliminar sua lista por completo!

O método pop() remove o último elemento da lista e nos retorna ele:

ciencias.pop() # 'biologia'
print(ciencias) # ['matemática', 'astronomia']

Finalmente, o método clear() esvazia a lista por completo:

ciencias.clear()
print(ciencias) # []

Construindo uma Lista com list()

Também é possível construirmos listas através do método construtor list(), veja:

pares = list((2,4,6,8))
print(pares) # [2, 4, 6, 8]

Operações com Listas

Podemos ainda executar diversas operações com listas:

primos = [2,7,11,13,17]
negativos = [-1,-2,-5,-8,-3]
reais = [1.5,3.7,3/4,1,-0.1]

Vamos agora concatenar a lista de primos e negativos (unir elas):

concat = primos + negativos
print(concat) # [2, 7, 11, 13, 17, -1, -2, -5, -8, -3]

Repetindo os elementos de uma lista duas vezes:

print(primos*2) # [2, 7, 11, 13, 17, 2, 7, 11, 13, 17]

O método sort() nos permite ordenar os elementos de uma lista in-place, em outras palavras, sem a necessidade de criar uma nova lista. Por exemplo:

reais.sort()
print(reais) # [-0.1, 0.75, 1, 1.5, 3.7]

Já o método sorted() é capaz de ordenar uma lista e nos retornar uma nova lista ordenada, sem modificar a nossa lista original. Por exemplo:

print(sorted(negativos)) # [-8, -5, -3, -2, -1]

Podemos ainda passar o argumento reverse como True para o método sorted(), dessa forma ele irá ordenar a lista em ordem decrescente:

print(sorted(negativos, reverse=True)) # [-1, -2, -3, -5, -8]

Dessa maneira nos serão trazidos os itens do maior para o menor.

É muito como querermos iterar sob os itens de uma lista, para, por exemplo, computar a soma de elementos de uma lista, neste caso específico vamos computar a soma de todos os elementos da lista de números primos:

total = 0
for i in range(len(primos)):
total += primos[i]
print(total) # 50

Podemos também executar este cálculo da seguinte maneira:

total = 0
for i in primos:
total += i
print(total) # 50

List Comprehension

List Comprehension são utilizadas para criarmos novas listas através de outros iteráveis, elas podem ser usadas para criarmos funcionalidades poderosas em apenas uma linha de código.

Para compreendermos melhor este conceito veremos diversos exemplos.

Iniciaremos definindo uma nova lista para trabalharmos:

valores = [-5, 7, 1, 0, 10, 100, 33, 2]

Se desejarmos elevar todos os números da lista valores ao quadrado, podemos usar um for loop tradicional:

quadrados = []
for v in valores:
quadrados.append(v**2)
print(quadrados) # [25, 49, 1, 0, 100, 10000, 1089, 4]

Com list comprehension esta operação se torna muito mais simples, podemos executá-la da seguinte maneira:

print([v**2 for v in valores]) # [25, 49, 1, 0, 100, 10000, 1089, 4]

Em vez de criarmos uma lista vazia e adicionar cada elemento ao final, como fizemos no primeiro exemplo ao criarmos a lista quadrados, nós simplesmente definimos a lista e seu conteúdo ao mesmo tempo seguindo este formato:

[expressão for membro in iterável]

Cada list comprehension em Python inclui três elementos:

  1. expressão é o próprio membro, uma chamada a um método ou qualquer outra expressão válida que retorna um valor. No exemplo acima, a expressão v**2 é o quadrado do valor do membro.
  2. membro é o objeto ou valor na lista ou iterável. No exemplo acima, o valor do membro é v.
  3. iterável é uma lista, conjunto, sequência, gerador ou qualquer outro objeto que pode retornar seus elementos um de cada vez. No exemplo acima, o iterável é valores.

A list comprehension pode ser usada para filtrarmos valores de uma lista, por exemplo, se quisermos selecionar apenas o valores divisíveis por 2, podemos usar o statement if:

print([v for v in valores if v%2 == 0]) # [0, 10, 100, 2]

Também podemos selecionar apenas os valores maiores do que 0:

print([v for v in valores if v > 0]) # [7, 1, 10, 100, 33, 2]

Até mesmo os valores menores ou iguais à 0:

print([v for v in valores if v <= 0]) # [-5, 0]

Listas aninhadas são uma forma comum de criar matrizes, que costumam ser usadas para fins matemáticos. No código abaixo somos capazes de criar uma matriz:

matriz = [[i for i in range(5)] for _ in range(6)]
print(matriz)
# [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

Vamos agora definir uma lista de temperaturas em Celsius e vamos usar uma list comprehension para converter as temperaturas para Fahrenheit:

celsius = [33.2, 26.7, 38.5, 40.8]
fahrenheit = [((float(9)/5)*t + 32) for t in celsius]
print(fahrenheit) # [91.76, 80.06, 101.3, 105.44]

Também podemos usar o poder das lists comprehensions para determinar o produto cruzado de dois conjuntos:

animais = ['gato','cachorro','lagarto']
alimentos = ['tomate','alface','abacate']
[(animal,alimento) for animal in animais for alimento in alimentos]
# [('gato', 'tomate'), ('gato', 'alface'), ('gato', 'abacate'),
# ('cachorro', 'tomate'), ('cachorro', 'alface'), ('cachorro', 'abacate'),
# ('lagarto', 'tomate'), ('lagarto', 'alface'), ('lagarto', 'abacate')]

Podemos ainda usá-las para calcular a raiz quadrada de uma grande quantidade de números com o auxílio da função range(), não podemos esquecer de importar a função sqrt() da biblioteca math:

from math import sqrt
[sqrt(n) for n in range(1000)]

No início do tutorial havíamos visto como calcular a soma de todos os itens de uma lista usando um for loop comum, vejamos como podemos fazer o mesmo com uma list comprehension usando o método sum():

soma = sum([n for n in range(37)])
print(soma) # 666

Para finalizar, vamos definir uma list comprehension que calcula números primos de 2 até x - 1, para isso vamos contar com a ajuda do método all():

[x for x in range(2, 50) if all(x % y != 0 for y in range(2, x))]
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Métodos das Listas

Existem diversos métodos construídos que podem ser usados com as listas para nos auxiliar em soluções, muitos deles já vimos como utilizar neste tutorial.

MétodoDescrição
append()Adiciona um único elemento para a lista.
extend()Adiciona um elemento de uma lista para outra lista
insert()Insere um elemento na lista
remove()Remove um elemento da lista
index()Retorna o índice de um elemento na lista
count()Retorna ocorrências de um elemento na lista
pop()Remove elemento de um determinado índice
reverse()Inverte a lista
sort()Organiza os elementos da lista
copy()Retorna uma cópia da lista
clear()Remove todos os itens da lista
any()Checa se algum elemento do iterável é True
all()Retorna True quando todos os elementos em um iterável são True
ascii()Retorna uma String
bool()Converte um valor para Boolean
enumerate()Retorna um Objeto Enumerate
filter()Constrói um iterador dos elementos que são True
iter()Retorna um iterador para um Objeto
list()Função que cria uma lista em Python
len()Retorna o comprimento / extensão da lista
max()Retorna o maior elemento
min()Retorna o menor elemento
map()Aplica uma função e retorna uma lista
reversed()Retorna um iterador invertido da sequência
slice()Cria um Objeto slice especificado por range()
sorted()Retorna uma lista organizada de um determinado iterável
sum()Adiciona os itens de um iterável
zip()Retorna um iterador de tuplas

Como podemos ver, as listas são uma estrutura de dados fundamental da linguagem Python e elas podem colaborar muito com nossos projetos devido a sua grande versatilidade.