Meu Google-fu falhou comigo.
No Python, os dois testes a seguir para igualdade são equivalentes?
n = 5
# Test one.
if n == 5:
print 'Yay!'
# Test two.
if n is 5:
print 'Yay!'
Isso vale para objetos em que você compararia instâncias ( list
digamos)?
Ok, então este tipo de resposta à minha pergunta:
L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
Então ==
testa o valor de onde is
testa para ver se eles são o mesmo objeto?
echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo
saída:False True False
.b = a[:]
parte de cópia da lista de operadores de fatias, por isso editei sua resposta para fazer um comentário lá. Parece que atingi o limite para não ter que revisar minhas edições antes de aplicá-las, por isso espero que seja legal com você. Independentemente disso, aqui é uma referência útil para saber como copiar listas que me deparei e teve de referência para descobrir o que estava fazendo: stackoverflow.com/a/2612815/4561887==
. Por5.0
exemplo, é um valor de ponto flutuante, enquanto5
é um número inteiro. Mas5.0 == 5
ainda retornaráTrue
porque eles representam o mesmo valor. Em termos de desempenho e digitação de pato,is
sempre é testado pelo intérprete comparando os endereços de memória do operando, enquanto==
que cabe ao objeto decidir se ele se define como igual a outra coisa.1000 is 10**3
avalia a verdade em Python 3.7 desde 10 ** 3 é tipoint
. Mas1000 is 1e3
avalia como False, pois 1e3 é do tipofloat
.1000 is 10**3
é verdade ou não , depende da implementação e depende do compilador que pré-avalia a expressão10**3
.x=10; 1000 is x**3
avalia comoFalse
.Existe uma regra simples para dizer quando usar
==
ouis
.==
é para igualdade de valor . Use-o quando desejar saber se dois objetos têm o mesmo valor.is
é para igualdade de referência . Use-o quando desejar saber se duas referências se referem ao mesmo objeto.Em geral, quando você está comparando algo com um tipo simples, geralmente está verificando a igualdade de valor , portanto, você deve usá-lo
==
. Por exemplo, a intenção do seu exemplo é provavelmente verificar se x tem um valor igual a 2 (==
), não sex
está literalmente se referindo ao mesmo objeto que 2.Algo mais a ser observado: devido à maneira como a implementação de referência CPython funciona, você obterá resultados inesperados e inconsistentes se usar por engano
is
para comparar a igualdade de referência em números inteiros:É praticamente o que esperávamos:
a
eb
têm o mesmo valor, mas são entidades distintas. Mas e isso?Isso é inconsistente com o resultado anterior. O que está acontecendo aqui? Acontece que a implementação de referência do Python armazena em cache objetos inteiros no intervalo -5..256 como instâncias singleton por motivos de desempenho. Aqui está um exemplo demonstrando isso:
Esse é outro motivo óbvio para não usar
is
: o comportamento é deixado para implementações quando você o usa erroneamente para obter igualdade de valor.fonte
a=500
eb=500
, só queria salientar que se você definira
eb
para um interger entre [-5, 256],a is b
na verdade retornaráTrue
. Mais informações aqui: stackoverflow.com/q/306313/7571052==
determina se os valores são iguais, enquantois
determina se eles são exatamente o mesmo objeto.fonte
Sim, eles têm uma diferença muito importante.
==
: verifique a igualdade - a semântica é que objetos equivalentes (que não são necessariamente o mesmo objeto) serão testados como iguais. Como a documentação diz :is
: verifique a identidade - a semântica é que o objeto (como mantido na memória) é o objeto. Mais uma vez, a documentação diz :Portanto, a verificação de identidade é igual à verificação da igualdade dos IDs dos objetos. Isso é,
é o mesmo que:
onde
id
é a função interna que retorna um número inteiro que "é garantido como único entre objetos existentes simultaneamente" (consultehelp(id)
) e ondea
eb
quaisquer objetos arbitrários.Outras instruções de uso
Você deve usar essas comparações para suas semânticas. Use
is
para verificar a identidade e==
verificar a igualdade.Então, em geral, usamos
is
para verificar a identidade. Isso geralmente é útil quando estamos verificando um objeto que deveria existir apenas uma vez na memória, chamado de "singleton" na documentação.Casos de uso para
is
incluir:None
Casos de uso usual para
==
incluem:O caso de uso geral, de novo, para
==
, é o objeto que você quer pode não ser o mesmo objeto, em vez disso, pode ser um equivalente de umDireções do PEP 8
O PEP 8, o guia de estilo oficial do Python para a biblioteca padrão também menciona dois casos de uso para
is
:Inferindo a igualdade da identidade
Se
is
for verdade, a igualdade geralmente pode ser inferida - logicamente, se um objeto é ele próprio, deve ser testado como equivalente a ele mesmo.Na maioria dos casos, essa lógica é verdadeira, mas depende da implementação do
__eq__
método especial. Como dizem os documentos ,e no interesse da consistência, recomenda:
Podemos ver que este é o comportamento padrão para objetos personalizados:
O contrapositivo também costuma ser verdadeiro - se algumas coisas não são iguais, você pode inferir que elas não são o mesmo objeto.
Como os testes de igualdade podem ser personalizados, essa inferência nem sempre é verdadeira para todos os tipos.
Uma exceção
Uma exceção notável é
nan
- ele sempre testa como diferente de si mesmo:Verificar a identidade pode ser muito mais rápido do que verificar a igualdade (o que pode exigir a verificação recursiva dos membros).
Mas não pode ser substituído por igualdade, onde você pode encontrar mais de um objeto como equivalente.
Observe que comparar a igualdade de listas e tuplas pressupõe que a identidade dos objetos seja igual (porque essa é uma verificação rápida). Isso pode criar contradições se a lógica for inconsistente - como é para
nan
:Um conto de advertência:
A questão está tentando usar
is
para comparar números inteiros. Você não deve assumir que uma instância de um número inteiro é a mesma instância que uma obtida por outra referência. Esta história explica o porquê.Um comentarista tinha um código que se baseava no fato de que pequenos números inteiros (-5 a 256 inclusive) são singletons em Python, em vez de verificar a igualdade.
Funcionou em desenvolvimento. Pode ter passado alguns unittests.
E funcionou na produção - até o código procurar um número inteiro maior que 256, quando falhou na produção.
Esta é uma falha de produção que poderia ter sido detectada na revisão de código ou possivelmente com um verificador de estilo.
Deixe-me enfatizar: não use
is
para comparar números inteiros.fonte
is None
é uma exceção, mas isso dito== None
também funciona ...is
para compararEnum
s.Qual é a diferença entre
is
e==
?==
eis
são diferentes comparação! Como outros já disseram:==
compara os valores dos objetos.is
compara as referências dos objetos.No Python, os nomes se referem a objetos, por exemplo, neste caso,
value1
evalue2
a umaint
instância que armazena o valor1000
:Porque
value2
se refere ao mesmo objetois
e==
daráTrue
:No exemplo a seguir, os nomes
value1
e sevalue2
referem aint
instâncias diferentes , mesmo que os dois armazenem o mesmo número inteiro:Porque o mesmo valor (inteiro) é armazenado
==
seráTrue
, por isso é muitas vezes chamado de "comparação de valor". No entantois
, retornaráFalse
porque estes são objetos diferentes:Quando usar qual?
Geralmente
is
é uma comparação muito mais rápida. É por isso que o CPython armazena em cache (ou talvez reutilize seria o melhor termo) certos objetos como números inteiros pequenos, algumas seqüências de caracteres etc. Mas isso deve ser tratado como um detalhe de implementação que pode (mesmo que improvável) mudar a qualquer momento sem aviso.Você só
is
deve usar se você:deseja comparar um valor a uma constante Python . As constantes em Python são:
None
True
1False
1NotImplemented
Ellipsis
__debug__
int is int
ouint is float
)np.ma.masked
do módulo NumPy)Em qualquer outro caso, você deve usar
==
para verificar a igualdade.Posso personalizar o comportamento?
Há um aspecto
==
que ainda não foi mencionado nas outras respostas: faz parte do Pythons "Data model" . Isso significa que seu comportamento pode ser personalizado usando o__eq__
método Por exemplo:Este é apenas um exemplo artificial para ilustrar que o método é realmente chamado:
Observe que por padrão (se nenhuma outra implementação de
__eq__
pode ser encontrada na classe ou nas superclasses)__eq__
usais
:Portanto, é realmente importante implementar
__eq__
se você deseja "mais" do que apenas comparação de referência para classes personalizadas!Por outro lado, você não pode personalizar os
is
cheques. Ele sempre será comparado apenas se você tiver a mesma referência.Essas comparações sempre retornam um valor booleano?
Como
__eq__
pode ser reimplementado ou substituído, não se limita a retornarTrue
ouFalse
. Ele poderia retornar nada (mas na maioria dos casos ele deve retornar um booleano!).Por exemplo, com matrizes NumPy
==
, retornará uma matriz:Mas os
is
cheques sempre retornamTrue
ouFalse
!1 Como Aaron Hall mencionou nos comentários:
Geralmente, você não deve fazer nenhuma verificação
is True
ouis False
porque normalmente as "verificações" são usadas em um contexto que converte implicitamente a condição em um booleano (por exemplo, em umaif
instrução). Portanto, fazer ais True
comparação e a conversão booleana implícita está fazendo mais trabalho do que apenas a conversão booleana - e você se limita a booleanos (o que não é considerado pitônico).Como o PEP8 menciona:
fonte
is
- nomes que apontam para booleanos devem ser verificados com um contexto booleano - comoif __debug__:
ouif not __debug__:
. Você nunca deve fazerif __debug__ is True:
ouif __debug__ == True:
- além disso, uma constante é apenas um valor semântico constante, não um singleton, portanto, verificaris
nesse caso não é semanticamente correto. Desafio você a encontrar uma fonte para apoiar suas afirmações - não acho que você encontrará uma.None
,True
,False
e__debug__
é o que você chamaria de "valor semântico constante", porque eles não podem ser realocados. Mas todos eles são singletons.is True
ou daif False
verificação (mas sim, essas são muito raras - mas se você as fizer, poderá usá-lasis
). É por isso que, mesmo CPython usa-los às vezes (por exemplo, aqui ou aqui )Eles são completamente diferentes .
is
verifica a identidade do objeto, enquanto==
verifica a igualdade (uma noção que depende dos tipos dos dois operandos).É apenas uma coincidência de sorte que "
is
" parece funcionar corretamente com números inteiros pequenos (por exemplo, 5 == 4 + 1). Isso ocorre porque o CPython otimiza o armazenamento de números inteiros no intervalo (-5 a 256), tornando-os singletons . Esse comportamento é totalmente dependente da implementação e não é garantido que seja preservado em todos os tipos de operações transformadoras menores.Por exemplo, o Python 3.5 também cria singletons de cadeias curtas, mas cortá-las interrompe esse comportamento:
fonte
https://docs.python.org/library/stdtypes.html#comparisons
is
testes para testes de identidade==
para igualdadeCada valor inteiro (pequeno) é mapeado para um único valor, portanto, cada 3 é idêntico e igual. Este é um detalhe de implementação, embora não faça parte das especificações de idioma
fonte
Sua resposta está correta. O
is
operador compara a identidade de dois objetos. O==
operador compara os valores de dois objetos.A identidade de um objeto nunca muda depois de criada; você pode pensar nele como o endereço do objeto na memória.
Você pode controlar o comportamento de comparação dos valores do objeto, definindo um
__cmp__
método ou um método de comparação rico como__eq__
.fonte
Dê uma olhada na questão do Stack Overflow. O operador "is" do Python se comporta inesperadamente com números inteiros .
O que mais se resume é que "
is
" verifica se eles são o mesmo objeto, não apenas iguais entre si (os números abaixo de 256 são um caso especial).fonte
Em poucas palavras,
is
verifica se duas referências apontam para o mesmo objeto ou não.==
verifica se dois objetos têm o mesmo valor ou não.fonte
Como John Feminella disse, na maioria das vezes você usará == e! = Porque seu objetivo é comparar valores. Gostaria apenas de categorizar o que você faria o resto do tempo:
Há uma e apenas uma instância de NoneType, ou seja, None é um singleton. Consequentemente
foo == None
efoo is None
significa o mesmo. No entanto, ois
teste é mais rápido e a convenção Pythonic deve ser usadafoo is None
.Se você está fazendo alguma introspecção ou mexendo com a coleta de lixo ou verificando se o seu dispositivo interno de cadeia de caracteres customizado está funcionando ou algo parecido, provavelmente você tem um caso de uso para
foo
isbar
.True e False também são (agora) singletons, mas não há nenhum caso de uso para
foo == True
e nenhum caso de uso parafoo is True
.fonte
A maioria deles já respondeu ao ponto. Apenas como uma observação adicional (baseada no meu entendimento e experiência, mas não de uma fonte documentada), a declaração
das respostas acima devem ser lidas como
. Cheguei a esta conclusão com base no teste abaixo:
Aqui, o conteúdo da lista e da tupla são iguais, mas o tipo / classe é diferente.
fonte
Diferença de Python entre is e igual (==)
Aqui está um exemplo para demonstrar a semelhança e a diferença.
fonte
Como as outras pessoas neste post respondem à pergunta em detalhes, eu enfatizaria principalmente a comparação entre
is
e==
para strings que podem dar resultados diferentes e eu recomendaria aos programadores que os usassem com cuidado.Para comparação de cadeias, certifique-se de usar em
==
vez deis
:Fora:
Mas no exemplo abaixo
==
eis
obterá resultados diferentes:Fora:
Conclusão:
Use com
is
cuidado para comparar entre stringsfonte