Eu li vários tutoriais em python (Dive Into Python, por exemplo) e a referência de linguagem no Python.org - não vejo por que a linguagem precisa de tuplas.
As tuplas não têm métodos comparados a uma lista ou conjunto, e se eu devo converter uma tupla em um conjunto ou lista para poder classificá-las, qual é o sentido de usar uma tupla em primeiro lugar?
Imutabilidade?
Por que alguém se importa se uma variável vive em um lugar diferente na memória do que quando foi originalmente alocada? Todo esse negócio de imutabilidade em Python parece ter sido enfatizado demais.
No C / C ++, se eu alocar um ponteiro e apontar para alguma memória válida, não me importo onde o endereço está localizado, desde que não seja nulo antes de usá-lo.
Sempre que faço referência a essa variável, não preciso saber se o ponteiro ainda está apontando para o endereço original ou não. Eu apenas verifico se há nulo e o uso (ou não).
No Python, quando eu aloco uma string (ou tupla), atribua-a a x e modifique a string, por que me importo se é o objeto original? Desde que a variável aponte para meus dados, isso é tudo o que importa.
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
x
ainda faz referência aos dados que eu quero, por que alguém precisa se preocupar se seu ID é igual ou diferente?
Respostas:
objetos imutáveis podem permitir otimização substancial; presumivelmente, é por isso que as strings também são imutáveis em Java, desenvolvidas separadamente, mas quase ao mesmo tempo que o Python, e praticamente tudo é imutável em linguagens verdadeiramente funcionais.
em Python em particular, apenas imutáveis podem ser laváveis (e, portanto, membros de conjuntos ou chaves em dicionários). Novamente, isso permite otimização, mas muito mais do que apenas "substancial" (projetar tabelas de hash decentes armazenando objetos completamente mutáveis é um pesadelo - você tira cópias de tudo assim que o hash ou o pesadelo de verificar se o hash do objeto mudou desde a última vez que você fez uma referência a ele;
Exemplo de problema de otimização:
fonte
random
chamadas (tente fazer exatamente isso, você verá!), Portanto, não é muito significativo. Experimentepython -mtimeit -s "x=23" "[x,x]"
e você verá uma aceleração mais significativa de 2 a 3 vezes para criar a tupla versus criar a lista.Nenhuma das respostas acima aponta o problema real das tuplas versus listas, que muitas novas no Python parecem não entender completamente.
Tuplas e listas servem a propósitos diferentes. As listas armazenam dados homogêneos. Você pode e deve ter uma lista como esta:
O motivo do uso correto das listas é porque esses são todos os tipos de dados homogêneos, especificamente os nomes das pessoas. Mas faça uma lista como esta:
Essa lista é o nome completo de uma pessoa e sua idade. Esse não é um tipo de dados. A maneira correta de armazenar essas informações é em uma tupla ou em um objeto. Digamos que temos alguns:
A imutabilidade e mutabilidade de Tuplas e Listas não é a principal diferença. Uma lista é uma lista do mesmo tipo de itens: arquivos, nomes, objetos. Tuplas são um agrupamento de diferentes tipos de objetos. Eles têm usos diferentes, e muitos codificadores Python abusam de listas para o que as tuplas são destinadas.
Por favor não.
Editar:
Eu acho que este post explica porque eu acho isso melhor do que eu: http://news.e-scribe.com/397
fonte
Nesse caso em particular, provavelmente não há razão. Esse não é um problema, pois esse não é um dos casos em que você considera usar uma tupla.
Como você aponta, as tuplas são imutáveis. As razões para ter tipos imutáveis se aplicam às tuplas:
Observe que uma implementação específica do Python pode não fazer uso de todos os recursos acima.
As chaves do dicionário devem ser imutáveis, caso contrário, alterar as propriedades de um objeto-chave pode invalidar invariantes da estrutura de dados subjacente. Assim, as tuplas podem ser potencialmente usadas como chaves. Isso é uma consequência da correção constante.
Veja também " Introdução às tuplas ", do Dive Into Python .
fonte
==
é implementado no nível da plataforma.(1,2,3) == (1,2,3)
. É mais uma questão de internar.Às vezes gostamos de usar objetos como chaves de dicionário
Pelo que vale, as tuplas recentemente (2.6+) cresceram
index()
e oscount()
métodosfonte
Sempre achei que ter dois tipos completamente separados para a mesma estrutura básica de dados (matrizes) era um design estranho, mas na prática não era um problema real. (Toda linguagem tem suas verrugas, inclusive o Python, mas isso não é importante.)
Essas são coisas diferentes. A mutabilidade não está relacionada ao local em que está armazenada na memória; significa que as coisas para as quais aponta não podem mudar.
Objetos Python não podem mudar de local após serem criados, mutáveis ou não. (Mais precisamente, o valor de id () não pode mudar - a mesma coisa, na prática.) O armazenamento interno de objetos mutáveis pode mudar, mas esse é um detalhe oculto da implementação.
Isso não está modificando ("mutando") a variável; está criando uma nova variável com o mesmo nome e descartando a antiga. Compare com uma operação de mutação:
Como outros já apontaram, isso permite usar matrizes como chaves para dicionários e outras estruturas de dados que precisam de imutabilidade.
Observe que as chaves dos dicionários não precisam ser completamente imutáveis. Somente a parte usada como chave precisa ser imutável; para alguns usos, essa é uma distinção importante. Por exemplo, você pode ter uma classe representando um usuário, que compara igualdade e um hash pelo nome de usuário exclusivo. Você pode então pendurar outros dados mutáveis na classe - "o usuário está logado" etc. etc. Como isso não afeta a igualdade ou o hash, é possível e perfeitamente válido usá-lo como chave em um dicionário. Isso não é muito comum em Python; Apenas aponto, já que várias pessoas alegaram que as chaves precisam ser "imutáveis", o que é apenas parcialmente correto. Eu usei isso muitas vezes com mapas e conjuntos de C ++.
fonte
Como o gnibbler ofereceu em um comentário, Guido teve uma opinião que não é totalmente aceita / apreciada: “listas são para dados homogêneos, tuplas são para dados heterogêneos”. Certamente, muitos dos opositores interpretaram isso como significando que todos os elementos de uma lista devem ser do mesmo tipo.
Eu gosto de ver de maneira diferente, não muito diferente dos outros no passado:
Note que eu considero alist homogêneo, mesmo que type (alist [1])! = Type (alist [2]).
Se eu puder alterar a ordem dos elementos e não apresentar problemas no meu código (além de suposições, por exemplo, "ele deve ser classificado"), uma lista deverá ser usada. Caso contrário (como na tupla
blue
acima), devo usar uma tupla.fonte
Eles são importantes, pois garantem ao chamador que o objeto pelo qual passarem não será alterado. Se você fizer isto:
O chamador não tem garantia do valor de a após a chamada. Contudo,
Agora você, como chamador ou como leitor deste código, sabe que a é o mesmo. Você sempre pode, nesse cenário, fazer uma cópia da lista e passar isso, mas agora está desperdiçando ciclos em vez de usar uma construção de linguagem que faz mais sentido semântico.
fonte
você pode ver aqui para alguma discussão sobre isso
fonte
Sua pergunta (e comentários de acompanhamento) concentram-se em saber se o id () muda durante uma tarefa. Focar esse efeito subsequente da diferença entre substituição imutável de objetos e modificação mutável de objetos, em vez da diferença em si, talvez não seja a melhor abordagem.
Antes de continuarmos, verifique se o comportamento demonstrado abaixo é o que você espera do Python.
Nesse caso, o conteúdo de a2 foi alterado, mesmo que apenas a1 tenha um novo valor atribuído. Contraste com o seguinte:
Neste último caso, substituímos a lista inteira, em vez de atualizar seu conteúdo. Com tipos imutáveis, como tuplas, esse é o único comportamento permitido.
Por que isso importa? Digamos que você tenha um ditado:
Usando uma tupla, o dicionário pode evitar que suas chaves sejam alteradas "de baixo para baixo" para itens com hash com um valor diferente. Isso é crítico para permitir uma implementação eficiente.
fonte