Compreensão de listas no Python

Em um sistema de cadastro de produtos que estou desenvolvendo em Python, para um mercado, temos a seguinte classe que representa um produto:

class Produto(object):
	
	def __init__(self, nome, valor, quantidade):
		self.__nome = nome
		self.__valor = valor
		self.__quantidade = quantidade

	def __repr__(self):
		return self.__nome

	def get_nome(self):
		return self.__nome

	def get_valor(self):
		return self.__valor

	def get_quantidade(self):
		return self.__quantidade

	def impressao(self):
		return "nome:%s valor:%s quantidade:%s" % (self.__nome, self.__valor, self.__quantidade)

Dentro desse sistema, recebi uma lista chamada produtos:

produtos = produtos_em_estoque()

Contendo os seguintes produtos:

nome:Arroz valor:10.5 quantidade:100
nome:Feijao valor:6.5 quantidade:80
nome:Refrigerante valor:3.0 quantidade:120
nome:Cafe valor:5.45 quantidade:75
nome:Sabao em po valor:8.75 quantidade:80
nome:Requeijao valor:3.5 quantidade:76
nome:Leite valor:2.5 quantidade:132
nome:pao de forma valor:2.0 quantidade:120
nome:Cafe valor:5.45 quantidade:75
nome:caixa de bombom valor:6.75 quantidade:93

Porém, o dono do mercado pediu para verificar todos os produtos que estão acabando, ou seja, com quantidade menores que 100. Uma solução procedural para esse problema seria criar um for, e então, dentro dele, adicionamos um if que verifica os produtos com quantidades menores que 100 e, se for verdade, adicionamos a uma nova lista contendo todos os produtos que estão acabando. Por fim, devolvemos essa nova lista:

poucas_qtd = []
for produto in produtos:
	if(produto.get_quantidade() < 100):
		poucas_qtd.append(produto)

print poucas_qtd

O resultado seria:

[Feijao, Cafe, Sabao em po, Requeijao, Cafe, caixa de bombom]

Para uma tarefa bem simples, escrevemos muito código… Em outras palavras, escrevemos 3 linhas de código para resolver um problema bem comum em uma lista! Será que tem como resolver isso de uma forma mais enxuta e objetiva?

No Python, além dos recursos básicos que encontramos em muitas linguagens de programação, isto é, instruções de for, if e else entre outras. Temos também um recurso bem interessante chamado compreensão de lista, que nos ajuda, e muito, na manipulação de dados de uma lista. Por exemplo, para resolver o mesmo problema que acabamos de ver utilizando a compreensão de lista, faríamos da seguinte forma:

poucas_qtd = [produto for produto in produtos if produto.get_quantidade() < 100]
print poucas_qtd

Vejamos o resultado:

[Feijao, Cafe, Sabao em po, Requeijao, Cafe, caixa de bombom]

Exatamente o mesmo resultado! Porém, veja que resolvemos dessa vez em uma única linha! E mais, sem a necessidade de criar uma lista vazia! Mas como isso aconteceu?

A compreensão de lista, itera sobre todos os elementos de uma lista e executa uma ação para cada item encontrado de acordo com o filtro que utilizamos. Em outras palavras, é descrita com a seguinte estrutura:

[ação a ser tomada, itens iterados, filtro]
  • ação a ser tomada: Ação desejada para cada item. (Nesse exemplo só devolvemos o item).
  • itens iterados: lista que queremos iterar e extrair seus itens.
  • filtro: Onde aplicamos as condições para devolver os itens de uma lista.

Suponhamos que dessa vez, o dono desse mercado pediu para verificar todos os produtos com valores abaixo de R$ 10,00, e então, para cada um desses produtos, acrescentar 10% ao valor original. Como faríamos isso? Será que apenas em modo procedural da certo? Para a nossa felicidade, por meio da compreensão de lista, podemos também realizar operações aritméticas! Vejamos como ficaria:

[produto.acrescentar_valor(produto.get_valor() * 0.10) for produto in produtos if produto.get_valor() < 10]

Se imprimirmos os nosso produtos:

for produto in produtos:
	print produto.impressao()

Temos o seguinte resultado:

nome:Arroz valor:10.5 quantidade:100
nome:Feijao valor:7.15 quantidade:80
nome:Refrigerante valor:3.3 quantidade:120
nome:Cafe valor:5.995 quantidade:75
nome:Sabao em po valor:9.625 quantidade:80
nome:Requeijao valor:3.85 quantidade:76
nome:Leite valor:2.75 quantidade:132
nome:pao de forma valor:2.2 quantidade:120
nome:Cafe valor:5.995 quantidade:75
nome:caixa de bombom valor:7.425 quantidade:93

Como podemos ver, os produtos: “Feijao, Refrigerante, Cafe, Sabao em po, Requeijao, Leite, pao de forma, Cafe e caixa de bombom”. Sofreram o acrescimento de 10% com um código de apenas 1 linha!

E aí, gostou da compreensão de lista? Que tal tentar agora mesmo substituir os seus fors e ifs por ela? Quer aprender mais sobre os recursos do python? Então de uma olhada nos nossos cursos online de python na Alura.


Content Editor at Alura and Software Developer

  • É basicamente um .where( do lambda no c#

    • Oi Houston, a questão do filtro é basicamente mesmo, só que a compreensão de lista é um recurso que já vem nativo em diversas linguagens (principalmente de linguagens com paradigma funcional). Obrigado pelo comentário 🙂

  • licensed

    o titulo fala de simplificar processamento, porem esta usando o if e iterando a lista do mesmo jeito. a diferenca eh escrever menos codigo, que dependendo do problema pode tornar bem ilegivel. gostaria de saber se utilizar list comprehension otimiza o codigo.

    • Olá Licensed, tudo bem? Ótima observação! Teoricamente temos a mesma coisa com uma outra “cara”, porém, além de ser resolvido em uma única linha, esse tipo de recurso é bastante usado em linguagens que utilizam o paradigma funcional, como por exemplo o erlang, que não nos disponibiliza estruturas de repetições como while ou for. E com certeza, dependendo do que você está fazendo, o código pode ficar complexo, mas nada impede que você chave funções dentro da list comprehension.

      Sobre performance, particularmente nunca fiz um teste que comprove que um é mais rápido do que o outro, é bem provável que dê pra notar quando está lidando com listas enormes. Porém, em uma pesquisa rápida, achei esse post que faz uma comparação de map, loop e comprehension list.

      Obrigado pelo comentário 🙂

  • Muito bom o post e a explicação Alex parabéns.

    • Opa Luiz! Obrigado pelo feedback! Fico contente que tenha gostado 🙂

Próximo ArtigoAlura entrevista: Julius Lima, criador do Wingbirds