Python: Append ou Extend? Adicionando elementos na lista
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 na nossa formação de Python para web na Alura e aprenda hoje mesmo os diversos recursos que essa linguagem nos oferece!