curso
Tutorial de compreensão de listas em Python
Execute e edite o código deste tutorial online
Executar códigoAo fazer ciência de dados, você pode querer ler listas de listas, filtrar nomes de colunas, remover vogais de uma lista ou achatar uma matriz. Você pode facilmente usar uma função lambda ou um loop for; como você bem sabe, há várias maneiras de fazer isso. Uma outra maneira de fazer isso é usar compreensões de lista.
Este tutorial abordará esse último tópico:
- Primeiro, você verá uma breve recapitulação do que são as listas do Python e como elas se comparam a outras estruturas de dados do Python;
- Em seguida, você mergulhará nas compreensões de listas do Python: você aprenderá mais sobre a matemática por trás das listas do Python, como construir compreensões de listas, como reescrevê-las como loops for ou funções lambda, .... Você não apenas lerá sobre isso, mas também fará alguns exercícios!
- Depois de dominar os conceitos básicos, também é hora de aperfeiçoar suas compreensões de lista adicionando condicionais a elas: você aprenderá como incluir condicionais em compreensões de lista e como lidar com várias condições if e instruções if-else.
- Por fim, você mergulhará nas compreensões de listas aninhadas para iterar várias vezes sobre as listas.
Se você também estiver interessado em lidar com compreensões de lista juntamente com iteradores e geradores? Confira o curso Python Data Science Toolbox da DataCamp!
Listas Python
Até agora, você provavelmente já brincou com valores que tinham vários tipos de dados. Você salvou cada valor em uma variável separada: cada variável representa um único valor. No entanto, na ciência de dados, você frequentemente trabalhará com muitos pontos de dados, o que dificultará o armazenamento de cada valor em uma variável separada. Em vez disso, você armazena todos esses valores em uma lista Python.
As listas são uma das quatro estruturas de dados incorporadas no Python. Outras estruturas de dados que você talvez conheça são tuplas, dicionários e conjuntos. Uma lista em Python é diferente de, por exemplo, int
ou bool
, no sentido de que é um tipo de dados composto: você pode agrupar valores em listas. Na verdade, esses valores não precisam ser do mesmo tipo: eles podem ser uma combinação de valores booleanos, String, inteiros, ....
É importante observar que as listas são coleções ordenadas de itens ou objetos. Isso torna as listas em Python "tipos de sequência", pois elas se comportam como uma sequência. Isso significa que elas podem ser iteradas; outros exemplos de sequências são strings, tuplas ou conjuntos.
Dica: se quiser saber mais, testar ou praticar seus conhecimentos sobre listas em Python, você pode fazer isso analisando as perguntas mais comuns sobre listas em Python aqui.
Agora, uma observação prática: você constrói uma lista com dois colchetes; dentro desses colchetes, você usará vírgulas para separar os valores. Em seguida, você pode atribuir sua lista a uma variável. Os valores que você coloca em uma lista Python podem ser de qualquer tipo de dados, até mesmo listas!
Dê uma olhada no exemplo de lista a seguir:
Dica: crie sua própria lista no shell IPython que está contido no trecho do DataCamp Light acima!
Compreensão da lista Python
Com a recapitulação das listas Python em mente, você pode ver facilmente que definir e criar listas em Python pode ser um trabalho cansativo: digitar todos os valores separadamente pode levar algum tempo e você pode facilmente cometer erros.
As compreensões de lista em Python são construídas da seguinte forma:
list_variable = [x for x in iterable]
Mas como você chega a essa maneira semelhante a uma fórmula de criar e usar essas construções em Python? Vamos nos aprofundar um pouco mais.
Compreensão de listas em Python: A matemática
Felizmente, o Python tem a solução para você: ele oferece uma maneira de implementar uma notação matemática para fazer isso: compreensão de lista.
Lembre-se de que, em matemática, as formas comuns de descrever listas (ou conjuntos, ou tuplas, ou vetores) são:
S = {x² : x in {0 ... 9}}
V = (1, 2, 4, 8, ..., 2¹²)
M = {x | x in S and x even}
Em outras palavras, você verá que as definições acima realmente dizem o seguinte:
- A sequência S é, na verdade, uma sequência que contém valores entre 0 e 9 incluídos que são elevados à potência de dois.
- A sequência V, por outro lado, contém o valor 2 que é elevado a uma determinada potência. Para o primeiro elemento da sequência, isso é 0, para o segundo é 1, e assim por diante, até que você chegue a 12.
- Por fim, a sequência M contém elementos da sequência S, mas somente os pares.
Se as definições acima causarem dor de cabeça a você, dê uma olhada nas listas reais que essas definições produziriam:
S = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
V = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096}
M = {0, 4, 16, 36, 64}
Você vê claramente o resultado de cada lista e as operações que foram descritas nelas!
Agora que você entendeu um pouco da matemática por trás das listas, pode traduzir ou implementar a notação matemática da construção de listas em Python usando compreensões de listas! Dê uma olhada nas seguintes linhas de código:
Tudo isso é muito parecido com as definições matemáticas que você acabou de ver, certo?
Não se preocupe se você estiver um pouco perdido neste ponto; mesmo que você não seja um gênio da matemática, essas compreensões de listas são bastante fáceis se você dedicar algum tempo para estudá-las. Dê uma segunda olhada mais de perto no código Python que você vê no trecho de código acima.
Você verá que o código informa isso:
- A lista S é construída com os colchetes que você leu acima na primeira seção. Nesses colchetes, você vê que há um elemento x, que é elevado à potência de 10. Agora, você só precisa saber para quantos valores (e quais valores!) você precisa elevar à potência de 2. Isso é determinado em
range(10)
. Considerando tudo isso, você pode deduzir que elevará todos os números, de 0 a 9, à potência de 2. - A lista V contém o valor base 2, que é elevado a uma determinada potência. Assim como antes, agora você precisa saber qual energia ou
i
será usada exatamente para fazer isso. Você vê quei
, nesse caso, faz parte derange(13)
, o que significa que você começa em 0 e vai até 12. Tudo isso significa que sua lista terá 13 valores - esses valores serão 2 elevado à potência 0, 1, 2, ... até 12. - Por fim, a lista M contém elementos que fazem parte de S se - e somente se - puderem ser divididos por 2 sem que haja sobras. O módulo precisa ser 0. Em outras palavras, a lista M é construída com os valores iguais que estão armazenados na lista S.
Agora que você viu tudo isso escrito, faz muito mais sentido, certo?
Recapitulação e prática
Em resumo, você vê que há alguns elementos que retornam em todas essas linhas de código:
- Os colchetes, que são uma assinatura das listas do Python;
- A palavra-chave
for
, seguida de uma variável que simboliza um item de lista; e - A palavra-chave
in
, seguida de uma sequência (que pode ser uma lista!).
E isso resulta no trecho de código que você viu no início desta seção:
list_variable = [x for x in iterable]
Agora é a sua vez de começar a usar as compreensões de lista em Python! Vamos nos ater às listas matemáticas que você já viu antes:
Compreensão de listas como uma alternativa para...
A compreensão de lista é um substituto completo para loops for, função lambda, bem como para as funções map()
, filter()
e reduce()
. Além disso, para algumas pessoas, a compreensão de listas pode até ser mais fácil de entender e usar na prática! Você lerá mais sobre isso na próxima seção!
No entanto, se você quiser saber mais sobre funções e funções lambda em Python, consulte nosso Tutorial de funções em Python.
Loops For
Como você já deve saber, os loops for são usados para repetir um bloco de código um número fixo de vezes. As compreensões de lista são, na verdade, boas alternativas aos loops for, pois são mais compactas. Considere o exemplo a seguir, que começa com a variável numbers
, definida como um intervalo de 0 a 10 (não incluído).
Lembre-se de que o número que você passa para a função range()
é, na verdade, o número de números inteiros que você deseja gerar, começando do zero, é claro. Isso significa que range(10)
retornará [0,1,2,3,4,5,6,7,8,9]
.
# Initialize `numbers`
numbers = range(10)
Se agora você quiser executar uma operação em cada elemento em numbers
, poderá fazer isso com um loop for, como este:
# Initialize `new_list`
new_list = []
# Add values to `new_list`
for n in numbers:
if n%2==0:
new_list.append(n**2)
# Print `new_list`
print(new_list)
[0, 4, 16, 36, 64]
Tudo isso é muito bom, mas agora considere o exemplo a seguir de uma compreensão de lista, em que você basicamente faz o mesmo com uma notação mais compacta:
# Create `new_list`
new_list = [n**2 for n in numbers if n%2==0]
# Print `new_list`
print(new_list)
[0, 4, 16, 36, 64]
Vamos estudar a diferença de desempenho entre a compreensão de lista e o loop for com um pequeno teste: você pode configurar isso rapidamente com a biblioteca timeit
, que pode ser usada para cronometrar pequenos trechos de código Python de forma simples. Nesse caso, os pequenos trechos de código que você testará são o loop for, que você colocará em uma função chamada power_two()
para sua conveniência, e a compreensão exata da lista que você formulou acima.
Observe que você também passa o número de execuções que deseja considerar. Nesse caso, isso é definido como 10000
no argumento number
.
# Import `timeit`
import timeit
# Print the execution time
print(timeit.timeit('[n**2 for n in range(10) if n%2==0]', number=10000))
0.05234622399802902
# Define `power_two()`
def power_two(numbers):
for n in numbers:
if n%2==0:
new_list.append(n**2)
return new_list
# Print the execution time
print(timeit.timeit('power_two(numbers)', globals=globals(), number=10000))
0.07795589299712447
Observe que, nesse último trecho de código, você também adicionou o argumento globals
, que fará com que o código seja executado dentro do seu namespace global atual. Isso é extremamente útil se você tiver uma função definida pelo usuário (UDF), como a função power_two()
no exemplo acima. Como alternativa, você também pode passar um parâmetro setup
que contenha uma instrução de importação. Você pode ler mais sobre isso aqui.
Dica: confira o tutorial Loops em Python da DataCamp para obter mais informações sobre loops em Python.
Funções Lambda com map()
, filter()
e reduce()
As funções lambda também são chamadas de "funções anônimas" ou "funções sem nome". Isso significa que você só usa esse tipo de função quando elas são criadas. As funções lambda emprestam seu nome da palavra-chave lambda
em Python, que é usada para declarar essas funções em vez da palavra-chave padrão def
.
Normalmente, você usa essas funções junto com as funções map()
, filter()
e reduce()
.
Como substituir map()
em combinação com funções Lambda
Você pode reescrever a combinação map()
e uma função lambda, como no exemplo abaixo:
# Initialize the `kilometer` list
kilometer = [39.2, 36.5, 37.3, 37.8]
# Construct `feet` with `map()`
feet = map(lambda x: float(3280.8399)*x, kilometer)
# Print `feet` as a list
print(list(feet))
[128608.92408000001, 119750.65635, 122375.32826999998, 124015.74822]
Agora, você pode substituir facilmente essa combinação de funções que definem a variável feet
por compreensões de lista, levando em conta os componentes sobre os quais você leu na seção anterior:
- Comece com os colchetes.
- Em seguida, adicione o corpo da função lambda entre os colchetes:
float(3280.8399)*x
. - Em seguida, adicione a palavra-chave
for
e certifique-se de repetir o elemento de sequênciax
, que você já referenciou ao adicionar o corpo da função lambda. - Não se esqueça de especificar de onde vem
x
: adicione a palavra-chavein
, seguida da sequência de onde você obteráx
. Nesse caso, você transformará os elementos da listakilometer
.
Se você fizer tudo isso, obterá o seguinte resultado:
# Convert `kilometer` to `feet`
feet = [float(3280.8399)*x for x in kilometer]
# Print `feet`
print(feet)
[128608.92408000001, 119750.65635, 122375.32826999998, 124015.74822]
filter()
e funções Lambda para listar compreensões
Agora que você viu como é fácil converter a função map()
em combinação com uma função lambda, você também pode lidar com o código que contém a função Python filter()
com funções lambda e reescrevê-lo também.
Considere o exemplo a seguir:
# Map the values of `feet` to integers
feet = list(map(int, feet))
# Filter `feet` to only include uneven distances
uneven = filter(lambda x: x%2, feet)
# Check the type of `uneven`
type(uneven)
# Print `uneven` as a list
print(list(uneven))
[122375, 124015]
Para reescrever as linhas de código no exemplo acima, você pode, na verdade, usar duas compreensões de lista, armazenadas nas variáveis feet
e uneven
.
Primeiro, você reescreve a função map()
, que é usada para converter os elementos da lista feet
em números inteiros. Em seguida, você aborda a função filter()
: você pega o corpo da função lambda, usa as palavras-chave for
e in
para conectar logicamente x
e feet
:
# Constructing `feet`
feet = [int(x) for x in feet]
# Print `feet`
print(feet)
# Get all uneven distances
uneven = [x%2 for x in feet]
# Print `uneven`
print(uneven)
[128608, 119750, 122375, 124015]
[0, 0, 1, 1]
Reduzir reduce()
e funções Lambda em Python
Por fim, você também pode reescrever as funções lambda que são usadas com a função reduce()
em linhas de código mais compactas. Dê uma olhada no exemplo a seguir:
# Import `reduce` from `functools`
from functools import reduce
# Reduce `feet` to `reduced_feet`
reduced_feet = reduce(lambda x,y: x+y, feet)
# Print `reduced_feet`
print(reduced_feet)
[128608, 119750, 122375, 124015]
494748
Observe que, no Python 3, a função reduce()
foi movida para o pacote functools
. Portanto, você precisará importar o módulo para usá-lo, como no exemplo de código acima.
O trecho de código acima é bastante extenso, não é?
Vamos reescrever esse trecho de código!
Cuidado! Você precisa levar em conta que não é possível usar y
. As compreensões de lista só funcionam com um único elemento, como o x
que você viu nos vários exemplos deste tutorial.
Como você vai resolver isso?
Bem, em casos como esse, as funções de agregação, como sum()
, podem ser úteis:
# Construct `reduced_feet`
reduced_feet = sum([x for x in feet])
# Print `reduced_feet`
print(reduced_feet)
494748
Observe que, quando você pensa nisso, o uso de funções de agregação ao reescrever a função reduce()
em combinação com uma função lambda faz sentido: é muito semelhante ao que você faz no SQL quando usa funções de agregação para limitar o número de registros que recebe de volta depois de executar a consulta. Nesse caso, você usa a função sum()
para agregar os elementos em feet
para obter apenas um valor definitivo!
Observe que, embora essa abordagem possa não ter o mesmo desempenho em SQL, esse é definitivamente o caminho a seguir quando você estiver trabalhando em Python!
Compreensões de lista com condicionais
Agora que você entendeu os conceitos básicos das compreensões de lista em Python, é hora de ajustar o fluxo de controle das suas compreensões com a ajuda das condicionais.
# Define `uneven`
uneven = [x/2 for x in feet if x%2==0]
# Print `uneven`
print(uneven)
[64304.0, 59875.0]
Observe que você pode reescrever facilmente o trecho de código acima com um loop for do Python!
# Initialize and empty list `uneven`
uneven = []
# Add values to `uneven`
for x in feet:
if x % 2 == 0:
x = x / 2
uneven.append(x)
# Print `uneven`
print(uneven)
[64304.0, 59875.0]
Múltiplas condições if
Agora que você entendeu como pode adicionar condições, é hora de converter o seguinte loop for em uma compreensão de lista com condicionais.
divided = []
for x in range(100):
if x%2 == 0 :
if x%6 == 0:
divided.append(x)
Tenha cuidado, você verá que o seguinte loop for contém duas condições! Pense cuidadosamente em como você resolverá isso.
divided = [x for x in range(100) if x % 2 == 0 if x % 6 == 0]
print(divided)
[0, 6, 12, 18, 24, 30, 36, 42, 48, 54, 60, 66, 72, 78, 84, 90, 96]
Condições If-Else
É claro que é muito mais comum você trabalhar com condicionais que envolvem mais de uma condição. É isso mesmo, você verá com mais frequência if
em combinação com elif
e else
. Agora, como você lida com isso se planeja reescrever seu código?
Dê uma olhada no exemplo a seguir de uma condicional mais complexa em um loop for:
[x+1 if x >= 120000 else x+5 for x in feet]
[128609, 119755, 122376, 124016]
Agora, observe o trecho de código a seguir, que é uma reescrita do trecho de código acima:
for x in feet:
if x >= 120000:
x + 1
else:
x+5
Você vê que esse é basicamente o mesmo código, mas reestruturado: o último for x in feet
agora inicializa o loop for. Depois disso, você adiciona a condição if x >= 120000
e a linha de código que deseja executar se essa condição for True
: x + 1
. Se, em vez disso, a condição for False
, a última parte do código em sua compreensão de lista será executada: x+5
.
Compreensões de listas aninhadas
Além das condicionais, você também pode ajustar suas compreensões de lista aninhando-as em outras compreensões de lista. Isso é útil quando você deseja trabalhar com listas de listas: gerar listas de listas, transpor listas de listas ou achatar listas de listas para listas regulares, por exemplo, torna-se extremamente fácil com as compreensões de listas aninhadas.
Dê uma olhada no exemplo a seguir:
list_of_list = [[1,2,3],[4,5,6],[7,8]]
# Flatten `list_of_list`
[y for x in list_of_list for y in x]
[1, 2, 3, 4, 5, 6, 7, 8]
Você atribui uma lista bastante simples de listas a uma variável list_of_list
. Na próxima linha, você executa uma compreensão de lista que retorna uma lista normal. O que realmente acontece é que você pega os elementos da lista ( y
) das listas aninhadas ( x
) em list_of_list
e retorna uma lista dos elementos da lista y
que estão incluídos em x
.
Você vê que a maioria das palavras-chave e dos elementos usados no exemplo de compreensão de lista aninhada são semelhantes aos que você usou nos exemplos de compreensão de lista simples:
- Colchetes
- Duas palavras-chave
for
, seguidas de uma variável que simboliza um item da lista de listas (x
) e um item de lista de uma lista aninhada (y
); e - Duas palavras-chave
in
, seguidas por uma lista de listas (list_of_list
) e um item de lista (x
).
A maioria dos componentes é usada apenas duas vezes e você sobe um nível (ou mais, depende de como você vê isso!).
Você leva algum tempo para se acostumar, mas é bastante simples, não é?
Vamos agora considerar outro exemplo, no qual você verá que também pode usar dois pares de colchetes para alterar a lógica da compreensão da lista aninhada:
matrix = [[1,2,3],[4,5,6],[7,8,9]]
[[row[i] for row in matrix] for i in range(3)]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Agora pratique: reescreva o trecho de código acima em um loop for aninhado. Se você precisar de algumas dicas sobre como realizar esse exercício, vá para uma das seções anteriores deste tutorial.
transposed = []
for i in range(3):
transposed_row = []
for row in matrix:
transposed_row.append(row[i])
transposed.append(transposed_row)
Você também pode usar compreensões de listas aninhadas quando precisar criar uma lista de listas que seja, na verdade, uma matriz. Veja o exemplo a seguir:
matrix = [[0 for col in range(4)] for row in range(3)]
matrix
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Dica: pratique suas habilidades de loop em Python e reescreva o trecho de código acima em um loop for aninhado!
Você pode encontrar a solução abaixo.
for x in range(3):
nested = []
matrix.append(nested)
for row in range(4):
nested.append(0)
Se você quiser fazer um trabalho extra, trabalhe na tradução desse loop for para um loop while. Você pode encontrar a solução abaixo:
x = 0
matrix =[]
while x < 3:
nested = []
y = 0
matrix.append(nested)
x = x+1
while y < 4:
nested.append(0)
y= y+1
Por fim, é bom saber que você também pode usar funções como int()
para converter as entradas da sua lista feet
em números inteiros. Ao encapsular o [int(x) for x in feet]
em outra compreensão de lista, você constrói uma matriz ou listas da sua lista com bastante facilidade:
[[int(x) for x in feet] for x in feet]
[[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015],
[128608, 119750, 122375, 124015]]
Domine Python para ciência de dados
Parabéns! Você chegou ao final deste tutorial, no qual abordou as compreensões de lista, um mecanismo usado com frequência no Python para ciência de dados. Agora que você entende o funcionamento desse mecanismo, está pronto para lidar também com as compreensões de dicionário, conjunto, ...!
Não se esqueça de que você pode praticar suas habilidades em Python diariamente com o modo de prática diária do DataCamp! Você pode encontrá-lo diretamente no seu painel. Se você ainda não conhece o modo de prática diária, leia aqui! E explore o catálogo completo de cursos de Python da DataCamp aqui.
Embora as compreensões de lista possam tornar nosso código mais sucinto, é importante garantir que nosso código final seja o mais legível possível, portanto, linhas únicas de código muito longas devem ser evitadas para garantir que nosso código seja de fácil utilização.
Perguntas frequentes sobre a compreensão da lista Python
O que é compreensão de lista em Python?
Uma sintaxe concisa para criar uma lista a partir de um intervalo ou de um objeto iterável, aplicando uma operação específica em cada um de seus itens. Seu desempenho é muito mais rápido do que o de suas alternativas, como loops for, funções lambda, condicionais, etc.
Quando usamos a compreensão de listas?
Quando precisamos criar uma lista Python a partir de um objeto de intervalo ou de um iterável (outra lista, tupla, conjunto etc.), aplicando uma determinada operação em cada item do objeto de entrada. Ele funciona melhor quando a expressão que está sendo avaliada é relativamente simples. Dois casos específicos de uso da compreensão de listas são a filtragem de um objeto de entrada e o achatamento de um iterável multidimensional (por exemplo, uma lista de listas).
Em que tipo de sequências a compreensão de listas opera?
Um objeto de intervalo ou um iterável, como uma string, outra lista, lista de listas, tupla, conjunto, dicionário etc. No caso de compreensões de listas aninhadas, é possível ter coleções de dados de diferentes tipos.
Quais são os principais elementos da sintaxe de compreensão de lista?
Colchetes envolvendo a compreensão de lista, uma variável referente a cada item de uma sequência de entrada, uma expressão a ser avaliada, a coleção de dados (ou coleções) à qual a expressão é aplicada, as palavras-chave obrigatórias for e in, as palavras-chave if, else, not (quando necessário), operadores matemáticos e de comparação.
Para quais construções do Python a compreensão de lista pode ser um substituto?
A compreensão de lista é uma alternativa mais lacônica aos loops for (inclusive os aninhados), à função lambda, às funções internas do Python map(), filter() e reduce() e às condicionais.
Quais são os benefícios de usar a compreensão de lista em Python?
Desempenho rápido, sintaxe compacta, código de uma linha fácil de ler e depurar, espaço vertical otimizado no programa.
Qual é a principal desvantagem da compreensão de listas?
A compreensão de listas pode ser difícil de implementar e ler em algumas circunstâncias, como, por exemplo, expressões muito complexas a serem avaliadas ou muitos loops aninhados.
Como achatar uma lista de listas?
Usando compreensões de listas aninhadas. Por exemplo, se você tiver list_of_lists = [[1, 2, 3, 4], [5, 6, 7], [8, 9]], podemos achatar essa lista de listas usando o seguinte trecho de código: [item for lst in list_of_lists for item in lst].
É possível usar uma atribuição dentro da expressão de uma compreensão de lista?
Sim, a partir do Python 3.8, mesmo que essa operação seja raramente usada. Para essa finalidade, você deve usar o operador de morsa :=. Por exemplo, a compreensão de lista a seguir cria 5 vezes um inteiro aleatório entre 1 e 10 inclusive (primeiro você precisa importar o random), verifica se ele é maior que 3 e, em caso afirmativo, atribui-o à variável x, que então é adicionada à lista que está sendo criada: [x for _ in range(5) if (x := random.randint(1, 10)) > 3].
Que outros tipos de compreensão existem no Python?
Há também a compreensão de conjunto, dicionário e gerador com uma sintaxe semelhante à da compreensão de lista. Não há compreensão de tuplas no Python.
Saiba mais sobre Python
curso
Python intermediário
curso