Compreensão de listas no Python

(Last Updated On: 28 de dezembro de 2016)

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.

Fique por dentro

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