O
is
operador não corresponde aos valores das variáveis, mas às próprias instâncias.
O que isso realmente significa?
Declarei duas variáveis nomeadas x
e y
atribuindo os mesmos valores em ambas as variáveis, mas retorna falso quando uso o is
operador.
Eu preciso de um esclarecimento. Aqui está meu código.
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
Respostas:
Você entendeu mal o que o
is
operador testa. Testa se duas variáveis apontam para o mesmo objeto , não se duas variáveis têm o mesmo valor.Da documentação para o
is
operador :Em
==
vez disso, use o operador:Isso imprime
True
.x
ey
são duas listas separadas :Se você usar a
id()
função, verá issox
ey
terá identificadores diferentes:mas se você atribuísse
y
ax
então ambos apontariam para o mesmo objeto:e
is
mostra que ambos são o mesmo objeto, ele retornaTrue
.Lembre-se de que em Python, os nomes são apenas rótulos que fazem referência a valores ; você pode ter vários nomes apontando para o mesmo objeto.
is
informa se dois nomes apontam para um mesmo objeto.==
informa se dois nomes se referem a objetos que têm o mesmo valor.fonte
A is B
é o mesmo queid(A) == id(B)
.id(A)
em uma variável e depois esperevariable == id(B)
que ainda funcione; seA
foi excluído nesse ínterim,B
poderia ter recebido o mesmo local de memória.\n
>>> y = 5\n
>>> x é y\n
Verdadeiro\n
>>> x == y\n
Verdadeiro\n
>>>\n
Outra duplicata estava perguntando por que duas strings iguais geralmente não são idênticas, o que realmente não foi respondido aqui:
Então, por que eles não são a mesma string? Especialmente por causa disso:
Vamos adiar a segunda parte um pouco. Como o primeiro pode ser verdade?
O intérprete teria que ter uma "tabela interna", uma tabela que mapeia valores de string para objetos de string, então toda vez que você tenta criar uma nova string com o conteúdo
'abc'
, você obtém o mesmo objeto. A Wikipedia tem uma discussão mais detalhada sobre como funciona o estágio.E o Python tem uma mesa de internação de strings; você pode internar strings manualmente com o
sys.intern
método.Na verdade, o Python tem permissão para internar automaticamente qualquer tipo imutável, mas não é obrigado a fazer isso. Implementações diferentes irão internalizar valores diferentes.
CPython (a implementação que você está usando se não sabe qual implementação está usando) internaliza automaticamente pequenos inteiros e alguns singletons especiais como
False
, mas não strings (ou inteiros grandes, ou tuplas pequenas, ou qualquer outra coisa). Você pode ver isso facilmente:OK, mas por que eram
z
ew
idênticos?Esse não é o intérprete internando automaticamente, mas sim os valores de dobramento do compilador.
Se a mesma seqüência de tempo de compilação aparece duas vezes no mesmo módulo (o que exatamente isto significa é difícil de definir-não é a mesma coisa que um literal de cadeia, porque
r'abc'
,'abc'
e'a' 'b' 'c'
são todos literais diferentes, mas a mesma cadeia, mas fácil de entender intuitivamente), o compilador criará apenas uma instância da string, com duas referências.Na verdade, o compilador pode ir ainda mais longe:
'ab' + 'c'
pode ser convertido para'abc'
pelo otimizador, caso em que pode ser dobrado junto com uma'abc'
constante no mesmo módulo.Novamente, isso é algo que o Python é permitido, mas não obrigatório. Mas, neste caso, CPython sempre dobra pequenas strings (e também, por exemplo, pequenas tuplas). (Embora o compilador instrução por instrução do interpretador interativo não execute a mesma otimização que o compilador módulo por vez, então você não verá exatamente os mesmos resultados interativamente.)
Então, o que você deve fazer a respeito disso como programador?
Bem ... nada. Você quase nunca tem motivos para se importar se dois valores imutáveis são idênticos. Se você quiser saber quando pode usar em
a is b
vez dea == b
, você está fazendo a pergunta errada. Use sempre,a == b
exceto em dois casos:x is None
.x
afetará oy
.fonte
w
ez
são idênticos por causa dos valores de dobramento do compilador, por que isso também funciona no REPL, mesmo usandoid()
para verificar as referências? Usando o REPL no Python 3.7is
só retorna verdadeiro se eles forem realmente o mesmo objeto. Se eles fossem iguais, uma mudança em um também apareceria no outro. Aqui está um exemplo da diferença.fonte
Provocado por uma pergunta duplicada , esta analogia pode funcionar:
fonte
is
eis not
são os dois operadores de identidade em Python.is
operador não compara os valores das variáveis, mas compara as identidades das variáveis. Considere isto:O exemplo acima mostra que a identidade (também pode ser o endereço de memória no Cpython) é diferente para ambos
a
eb
(embora seus valores sejam os mesmos). É por isso que quando você diz quea is b
ele retorna falso devido à incompatibilidade nas identidades de ambos os operandos. No entanto, quando você diza == b
, ele retorna verdadeiro porque o==
operação apenas verifica se ambos os operandos têm o mesmo valor atribuído a eles.Exemplo interessante (para a nota extra):
No exemplo acima, embora
a
eb
sejam duas variáveis diferentes,a is b
retornadoTrue
. Isso ocorre porque o tipo dea
éint
que é um objeto imutável. Então python (eu acho que para economizar memória) alocou o mesmo objeto parab
quando foi criado com o mesmo valor. Portanto, neste caso, as identidades das variáveis corresponderam ea is b
acabaram por serTrue
.Isso se aplica a todos os objetos imutáveis:
Espero que ajude.
fonte
-5
ou maior do que256
em Python será False. Python armazena números em cache no intervalo [-5, 256].x is y
é o mesmo queid(x) == id(y)
comparar a identidade de objetos.Como @ tomasz-kurgan apontou no comentário abaixo
is
operador se comporta de maneira incomum com certos objetos.Por exemplo
Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
fonte
Como você pode verificar aqui, para pequenos números inteiros. Números acima de 257 não são pequenos, por isso é calculado como um objeto diferente.
É melhor usar
==
nesse caso.Mais informações estão aqui: http://docs.python.org/2/c-api/int.html
fonte
X aponta para uma matriz, Y aponta para uma matriz diferente. Essas matrizes são idênticas, mas o
is
operador olhará para esses ponteiros, que não são idênticos.fonte
is
funcionalidade do operador mostra isso.id
menos que você peça por ele.Ele compara a identidade do objeto, ou seja, se as variáveis se referem ao mesmo objeto na memória. É como
==
em Java ou C (ao comparar ponteiros).fonte
Um exemplo simples com frutas
Resultado:
Se você tentar
O resultado é diferente:
Isso ocorre porque o operador == compara apenas o conteúdo da variável. Para comparar as identidades de 2 variáveis, use o operador is
Para imprimir o número de identificação:
fonte
O
is
operador nada mais é do que uma versão em inglês do==
. Como os IDs das duas listas são diferentes, a resposta é falsa. Podes tentar:* Porque os IDs de ambas as listas seriam os mesmos
fonte
is
não é 'uma versão em inglês de==
'