Adicionando elementos na lista do Python: append ou extend?

(Last Updated On: 24 de Janeiro de 2017)

No desenvolvimento de qualquer sistema, é muito comum lidarmos com listas, como por exemplo, uma lista de produtos. Suponhamos que tenhamos a seguinte representação de um produto:

class Produto(object):
	
	def __init__(self, nome, valor):
		self.__nome = nome
		self.__valor = valor
		
	def __repr__(self):
		return "nome:%s valor:%s" % (self.__nome, self.__valor)

	def get_nome(self):
		return self.__nome

	def get_valor(self):
		return self.__valor

Então temos uma lista com alguns produtos:

from model import Produto

chocolate = Produto("Chocolate", 4.35)
refrigerante = Produto("Refrigerante", 3.75)
feijao = Produto("Feijao", 10.5)
produtos = [chocolate, refrigerante, feijao]

print produtos

Se executarmos esse código, temos o seguinte resultado:

[nome:Chocolate valor:4.35, nome:Refrigerante valor:3.75, 
nome:Feijao valor:10.5]

Por enquanto, tudo ocorrendo conforme o esperado, mas, e se quisermos adicionar um novo produto nessa lista? Como podemos fazer isso? Nas listas do Python, existem duas funções capazes de adicionar elementos, que são a append e a extend. Vamos então testá-las! Começaremos pelo append:

produto4 = Produto("Queijo", 4.25)
produtos.append(produto4)

print produtos

Vejamos qual é o resultado:

[nome:Chocolate valor:4.35, nome:Refrigerante valor:3.75, 
nome:Feijao valor:10.5, nome:Queijo valor:4.25]

Aparentemente ocorreu tudo conforme o esperado. Então vamos testar a função extend:

produto4 = Produto("Queijo", 4.25)
produtos.extend(produto4)

print produtos

Testando o código novamente:

TypeError: 'Produto' object is not iterable

Opa! Parece que o extend não consegue adicionar um objeto na lista… Será mesmo? Se analisarmos a mensagem de erro, ela nos informa que o objeto do tipo “Produto” não é iterable, mas o que será que isso significa?

O extend, diferente do append, itera sobre o elemento que deseja adicionar, ou seja, envolve o argumento passado por parâmetro dentro de um laço, e então, adiciona os valores contidos dentro desse parâmetro, nesse caso, ele tentou fazer isso com o objeto do tipo Produto. É justamente por isso que não foi possível adicionar o objeto do tipo Produto e apresentou esse erro.

Então significa que não podemos utilizar o extend para adicionar objetos?

Não exatamente!

Uma solução para esse problema é, ao invés de enviar um objeto puro, mandar como parâmetro uma estrutura iterável que contenha um objeto do tipo “Produto”, ou seja, enviar uma lista que contenha um Produto!

produto4 = Produto("Queijo", 4.25)
produtos.extend([produto4])

print produtos

Será que agora funciona? Vejamos o resultado:

[nome:Chocolate valor:4.35, nome:Refrigerante valor:3.75, 
nome:Feijao valor:10.5, nome:Queijo valor:4.25]

Funcionou como o esperado! Entretanto, adicionamos apenas um único elemento! E se quiséssemos adicionar vários elementos? Em outras palavras, adicionar uma lista de produtos novos. Será que funcionaria sem nenhum problema? Vamos testar primeiro com o append:

produto_novo1 = Produto("suco natural", 4.5)
produto_novo2 = Produto("pao de forma", 3.0)

produtos_novos = [produto_novo1, produto_novo2]

produtos.append(produtos_novos)

print produtos

Testando o código temos o seguinte resultado:

[nome:Chocolate valor:4.35, nome:Refrigerante valor:3.75, 
nome:Feijao valor:10.5, 
[nome:suco natural valor:4.5, nome:pao de forma valor:3.0]]

Aparentemente funcionou, mas repara que ao invés de adicionar cada produto na lista de produtos, ele adicionou uma lista inteira! Ou seja, quando utilizamos o append ele simplesmente adiciona o valor completo na lista. Mas e se utilizarmos o extend? Será que funciona? Isto é, adiciona produto por produto? Vamos verificar:

produto_novo1 = Produto("suco natural", 4.5)
produto_novo2 = Produto("pao de forma", 3.0)

produtos_novos = [produto_novo1, produto_novo2]

produtos.extend(produtos_novos)

print produtos

Rodando novamente o código:

[nome:Chocolate valor:4.35, nome:Refrigerante valor:3.75, 
nome:Feijao valor:10.5, nome:suco natural valor:4.5, 
nome:pao de forma valor:3.0]

Funcionou conforme o esperado! Portanto concluímos que as duas funções funcionam da seguinte forma:

  • append: Adiciona qualquer valor completo, por exemplo, se enviarmos um objeto, ele adiciona o objeto, se enviarmos uma lista, ele adiciona a lista inteira ao invés de seus itens.
  • extend: Adiciona itens de uma estrutura iterável, por exemplo, se enviarmos um objeto puro, ele não sabe como adicionar, porém, se enviarmos esse mesmo objeto dentro de uma lista, ele varrerá a lista e adicionará esse objeto e, caso exista outros, os demais dentro da lista.

Podemos ver claramente a diferença entre as duas funções no momento que tentamos adicionar uma string, por exemplo, a string “chocolate”:

  • Append:
    palavras = []
    
    palavras.append("chocolate")
    
    print palavras
    

    Resultado do append:

    ['chocolate']
    
  • Extend:
    palavras = []
    
    palavras.extend("chocolate")
    
    print palavras
    

    Resultado do extend:

    ['c', 'h', 'o', 'c', 'o', 'l', 'a', 't', 'e']
    

Veja que, enquanto o append adicionou toda a string, o extend adicionou letra por letra, pois a string, por de trás dos panos, é um array de char, portanto, ele varre esse array, isto é, essa estrutura iterável, e adiciona cada item.

Sabia dessa diferença no momento de adicionar algum elemento nas listas do Python? Não sabia? Quer aprender mais? Então dê uma olhada nos nossos cursos online de Python na Alura e aprenda hoje mesmo os diversos recursos que essa linguagem nos oferece!

FIQUE POR DENTRO

Content Editor at Alura and Software Developer

Próximo ArtigoQuando 1 não é 1 no SQL?