Pergunta

Google-fu me falhou.

Em Python, são os seguintes dois testes para a igualdade equivalente?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

Será que isso é verdadeiro para objetos onde você estaria comparando casos (uma palavra a dizer list)?

Ok, então este tipo de respostas a minha pergunta:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

Assim valor testes == onde os testes is para ver se eles são o mesmo objeto?

Foi útil?

Solução

is voltará True se duas variáveis ??apontam para o mesmo objeto, == se os objetos referidos pelas variáveis ??são iguais.

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True
>>> b = a[:] # Make a new copy of list `a` via the slice operator, and assign it to variable `b`
>>> b is a
False
>>> b == a
True

No seu caso, o segundo teste só funciona porque Python caches pequenos objetos inteiros, que é um detalhe de implementação. Para inteiros maiores, isso não funciona:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

O mesmo vale para strings literais:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

Por favor, veja esta pergunta também.

Outras dicas

Há uma regra simples para lhe dizer quando usar == ou is.

  • == é pela igualdade valor . Use-o quando você gostaria de saber se dois objetos têm o mesmo valor.
  • is é pela igualdade referência . Use-o quando você gostaria de saber se duas referências se referem ao mesmo objeto.

Em geral, quando você está comparando algo para um tipo simples, que normalmente são a verificação de valor igualdade , então você deve usar ==. Por exemplo, a intenção de seu exemplo é, provavelmente, para verificar se x tem um valor igual a 2 (==), não se x é, literalmente, referindo-se ao mesmo objeto como 2.


Outra coisa a nota: devido à maneira como as obras de implantação referência CPython, você poderá obter resultados inesperados e inconsistentes se você por engano usar is para comparar a igualdade de referência em inteiros:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

Isso é muito bonito o que esperávamos: a e b têm o mesmo valor, mas são entidades distintas. Mas o que sobre isso?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

Isto é inconsistente com o resultado mais cedo. O que está acontecendo aqui? Acontece que a implementação de referência de caches Python inteiro objectos na área de -5..256 como instâncias únicas por razões de desempenho. Aqui está um exemplo que demonstra o seguinte:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

Esta é outra razão óbvia para não usar is:. O comportamento é deixada para implementações quando você estiver usando-o erroneamente pela igualdade de valor

== determina se os valores são iguais, enquanto is determina se eles são exatamente o mesmo objeto e igualar.

Existe uma diferença entre == e is em Python?

Sim, eles têm uma diferença muito importante.

== : cheque de igualdade - a semântica é que os objetos equivalentes (que não são necessariamente o mesmo objeto) vai testar como iguais. Como o documentação diz :

Os operadores <,>, ==,> =, <= e! = Comparar os valores de dois objetos.

is : verificação de identidade - a semântica é que o objeto (como realizado em memória) é o objeto. Novamente, a documentação diz :

Os operadores is e teste is not para a identidade do objeto: x is y é verdade se e somente se x e y são o mesmo objeto. identidade do objeto é determinado utilizando a função id(). x is not y produz o inverso valor de verdade.

Assim, a verificação de identidade é o mesmo que a verificação da igualdade entre os IDs dos objetos. Ou seja,

a is b

é o mesmo que:

id(a) == id(b)

onde id é a função interna que retorna um inteiro que "é garantido para ser único entre os objetos simultaneamente existentes" (ver help(id)) e onde a e b quaisquer objetos arbitrários.

Other Directions Uso

Você deve usar essas comparações para sua semântica. Use is para verificar a identidade e == para verificar a igualdade.

PEP 8, o guia oficial estilo Python para a biblioteca padrão também menciona dois casos de uso para is :

Comparações com singletons como None deve sempre ser feito com is ou is not, nunca os operadores de igualdade.

Além disso, cuidado de escrever if x quando você if x is not None realmente média - por exemplo. ao testar se uma variável ou argumento de que o padrão é None foi criado para algum outro valor. O outro valor pode ter um tipo (tais como um recipiente) que poderiam ser falsas em um contexto booleano!

Inferring igualdade de identidade

Se is é verdade, igualdade pode normalmente ser inferida - logicamente, se um objeto é em si mesmo, então ele deve testar como equivalente a si mesmo.

Na maioria dos casos esta lógica é verdade, mas isso depende da implementação do método __eq__ especial. Como o docs digamos,

O comportamento padrão para comparação de igualdade (== e !=) baseia-se a identidade dos objetos. Daí, comparação de igualdade de instâncias com os mesmos resultados de identidade em igualdade, e comparação de igualdade de instâncias com identidades diferentes resulta em desigualdade. UMA motivação para esse comportamento padrão é o desejo que todos os objetos deve ser reflexiva (isto é, X é y implica x == y).

e em uma questão de coerência, recomenda:

comparação Igualdade deve ser reflexiva. Em outras palavras, idênticos objetos deve comparar iguais:

x is y implica x == y

Podemos ver que este é o comportamento padrão para objetos personalizados:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

O contrapositiva também é geralmente verdade - se algumas coisas teste como not igualar, geralmente você pode inferir que eles não são o mesmo objeto.

Uma vez que testes de igualdade pode ser personalizado, essa inferência nem sempre são verdadeiras para todos os tipos.

Uma exceção

Uma exceção notável é nan - ele sempre não testa como igual a si mesmo:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

Verificação de identidade pode ser muito um muito mais rápido verificar que a verificação de igualdade (o que pode exigir membros de forma recursiva verificação).

Mas ele não pode ser substituído por igualdade, onde você pode encontrar mais de um objeto como equivalente.

Note que, comparando a igualdade de listas e tuplas irá assumir que a identidade de objetos são iguais (porque esta é uma verificação rápida). Isso pode criar contradições se a lógica é inconsistente - como é para nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

A Cautionary Tale:

A questão está tentando usar is para comparar inteiros. Não se deve assumir que um exemplo de um número inteiro, é a mesma como um exemplo obtido por outra referência. Esta história explica o porquê.

Um comentarista tinha código que contou com o fato de que pequenos números inteiros (-5 a 256 inclusive) são singletons em Python, em vez de verificar a igualdade.

Uau, isso pode levar a alguns erros insidiosos. Eu tinha algum código que verificado se a é b, que funcionou como eu queria, porque a e b são normalmente pequenas quantidades. O bug só aconteceu hoje, depois de seis meses de produção, porque a e b foram finalmente grande o suficiente para não ser armazenado em cache. - gwg

Ele trabalhou no desenvolvimento. Ele pode ter passado alguns UnitTests.

E funcionou na produção - até que o código verificado para um número inteiro maior do que 256, no ponto em que ele falhou na produção.

Esta é uma falha de produção que poderiam ter sido pego em revisão de código ou, eventualmente, com um estilo-checker.

Deixe-me enfatizar: não use is para comparar inteiros

.

O que é a diferença entre is e ==?

== e is estão comparação diferente! Como outros já disse:

  • == compara os valores dos objetos.
  • is compara as referências dos objetos.

Nomes em Python se referir a objetos, por exemplo, neste caso value1 e value2 referem-se a uma instância int armazenar o valor 1000:

value1 = 1000
value2 = value1

 enter descrição da imagem aqui

Como value2 refere-se ao mesmo is objecto e == dará True:

>>> value1 == value2
True
>>> value1 is value2
True

No exemplo a seguir os nomes value1 e value2 referem-se a diferentes instâncias int, mesmo se ambos loja o mesmo número inteiro:

>>> value1 = 1000
>>> value2 = 1000

 enter descrição da imagem aqui

Porque o mesmo valor (inteiro) é armazenado == será True, é por isso que muitas vezes é chamado de "comparação de valor". No entanto is voltará False porque estes são diferentes objetos:

>>> value1 == value2
True
>>> value1 is value2
False

Quando usar o que?

Geralmente is é uma comparação muito mais rápido. É por isso que caches CPython (ou talvez reutilizações seria o melhor termo) certos objetos como pequenos números inteiros, algumas cordas, etc. Mas isso deve ser tratado como detalhe de implementação que poderia ( mesmo se a mudança improvável) em qualquer ponto sem aviso prévio.

Você deve só usam is se você:

  • querer verificar se dois objetos são realmente o mesmo objeto (não apenas o mesmo "valor"). Um exemplo pode ser se você usar um objeto singleton tão constante.
  • querer comparar um valor a uma Python constante . As constantes em Python são:

    • None
    • True 1
    • False 1
    • NotImplemented
    • Ellipsis
    • __debug__
    • classes (por exemplo int is int ou int is float)
    • não poderia ser constantes adicionais em built-in módulos ou módulos do 3o partido. Por exemplo np.ma.masked do módulo NumPy )

Em qualquer outro caso você deve usar == para verificar se há igualdade.

Posso personalizar o comportamento?

Há algum aspecto para == que não tenha sido já mencionado em outras respostas: É parte do Pythons "modelo de dados" . Isso significa que o seu comportamento pode ser personalizado usando o href="https://docs.python.org/reference/datamodel.html#object.__eq__" rel="noreferrer"> método __eq__ . Por exemplo:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

Este é apenas um exemplo artificial para ilustrar que o método é realmente chamado:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

Note que, por padrão (se não houver outra implementação de __eq__ podem ser encontrados na classe ou as superclasses) usos __eq__ is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

Por isso, é realmente importante para implementar __eq__ se você quiser "mais" do que apenas referência-comparação para classes personalizadas!

Por outro lado, você não pode personalizar is checks. Ele vai sempre comparar apenas se você tiver a mesma referência.

Será que essas comparações sempre retornam um boolean?

Porque __eq__ pode ser re-implementadas ou substituído, não é limitado a True retorno ou False. É pode retornar nada (mas na maioria dos casos ele deve retornar um booleano!).

Por exemplo, com matrizes Numpy o == retornará uma matriz:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

Mas cheques is sempre retornará True ou False!


1 Como Aaron Hall mencionado nos comentários:

Geralmente você não deve fazer nenhum is True ou is False cheques porque normalmente se usa esses "cheques" em um contexto que converte implicitamente o condição para um booleano (por exemplo, em uma declaração if). Então, fazer a comparação is True e o elenco boolean implícita está fazendo mais trabalho do que simplesmente fazer o elenco boolean -. E você se limitar a booleans (que não é considerado pythônico)

Como PEP8 menciona:

Não compare valores booleanos para True ou False usando ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

Eles são completamente diferente . cheques is para a identidade do objeto, enquanto os cheques == para a igualdade (uma noção que depende tipos os dois operandos).

É apenas uma feliz coincidência que "is" parece funcionar corretamente com números inteiros pequenos (por exemplo, 5 == 4 + 1). Isso é porque CPython otimiza o armazenamento de inteiros no intervalo (-5 256), tornando-os singletons . Este comportamento é totalmente dependente de implementação e não garantido para ser preservado sob todos os tipos de operações transformadoras menores.

Por exemplo, Python 3.5 também faz seqüências curtas singletons, mas cortando-lhes perturba esse comportamento:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

https://docs.python.org/library/stdtypes.html#comparisons

testa is de identidade testes == para a igualdade

Cada (pequena) valor inteiro é mapeado para um valor único, de modo a cada 3 é idêntica e igual. Este é um detalhe de implementação, não faz parte da especificação linguagem embora

A sua resposta está correta. O operador is compara a identidade dos dois objetos. O operador == compara os valores de dois objetos.

A identidade de um objeto nunca muda uma vez que foi criado; você pode pensar nisso como o endereço do objeto na memória.

pode controlar o comportamento de comparação dos valores de objectos através da definição de um método __cmp__ ou um comparação rica método como __eq__.

O operador == compara os valores de ambos os operandos e cheques pela igualdade de valor. Considerando que os controlos do operador is se ambos os operandos se referir ao mesmo objeto ou não.

a = [1,2,3,4]
b = a
print(a == b) # true
print(a is b) # true

Mas se fizermos

b = a[:] # b now references a copy of a
print(a == b) # true
print(a is b) # false
print(a is not b) # true

Basicamente, is pode ser pensado como uma abreviação para id(a) == id(b). No entanto, além deste, existem peculiaridades do ambiente de tempo de execução que complicar ainda mais as coisas. seqüências curtas e pequenos números inteiros retornará True quando comparado com is, devido à máquina de Python tentar usar menos memória para objetos idênticos.

a = 'python'
b = 'python'

print(a == b) # true
print(a is b) # true

Tenha um olhar em questão Stack Overflow “é” se comporta operador do Python inesperadamente com números inteiros .

O que na maior parte resume-se a que os controlos "is" para ver se eles são o mesmo objeto, não apenas iguais uns aos outros (os números abaixo de 256 são um caso especial).

Como John Feminella disse, na maioria das vezes você vai usar == e! = Porque o seu objetivo é comparar valores. Eu só gostaria de categorizar o que você faria o resto do tempo:

Há uma e apenas uma instância de NoneType ou seja Nenhum é um singleton. Consequentemente foo == None e foo is None significam a mesma. No entanto, o teste is é mais rápido e a convenção Pythonic é usar foo is None.

Se você está fazendo alguma introspecção ou mucking com coleta de lixo ou verificar se a cadeia de custom-built internar dispositivo está funcionando ou afins, então você provavelmente tem um caso de uso para foo é bar.

Verdadeiro e Falso também são (agora) singletons, mas não há nenhum caso de uso para foo == True e nenhum caso de uso para foo is True.

A maioria deles já respondeu ao ponto. Assim como uma nota adicional (com base na minha compreensão e experimentação, mas não de uma fonte documentada), a declaração

== se os objetos referidos pelas variáveis ??são iguais

a partir de respostas acima deve ser lido como

== se os objetos referidos pelas variáveis ??são iguais e objetos pertencentes ao mesmo tipo / classe

. Cheguei a esta conclusão com base na abaixo de teste:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Aqui o conteúdo da lista e tupla são os mesmos, mas o tipo / classe são diferentes.

Em suma, verifica is se duas referências apontam para o mesmo objeto ou not.== verifica se dois objetos têm o mesmo valor ou não.

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

Na verdade, eu queria acrescentar isso como um comentário, mas não podia embelezar-lo facilmente, portanto, acrescentando como uma resposta, por favor, não consideram isso como uma resposta.

Este é o que eu fiz para entender -

executar após um por um e entender de saída em cada etapa

a = [1,2]
b = [1,2,3]
b.pop()
id(a)
id(b)
a is b
a == b

Como os outros povos neste resposta pós a questão em detalhes, eu o faria enfatizar principalmente a comparação entre is e == para cadeias que podem dar resultados diferentes e eu faria programadores desejo de cuidado usá-los.

Para comparação de string, certifique-se de uso == vez de is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Out:

str is hello
str == hello

Mas no exemplo abaixo == e is vai obter resultados diferentes:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

Out:

str == hello sam

Conclusão:

Use is cuidadosamente para comparar entre as cordas

Python diferença entre é e iguais (==)

O operador is pode parecer o mesmo que o operador de igualdade, mas eles não são os mesmos.

A é verifica se ambas as variáveis ??apontam para o mesmo objeto enquanto o sinal == verifica se os valores das duas variáveis ??são os mesmos.

Portanto, se o é retorna verdadeiro então a igualdade é definitivamente É verdade, mas o oposto pode ou não ser verdade.

Aqui está um exemplo para demonstrar a semelhança ea diferença.

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

"==" compara valores

"é" compara objetos subjacentes

# this pgm is to show you the diff b/n == and is

# a==b and a is b

# == compares values
# is compares references i.e compares wether two variables refer to same object(memory)

a=10
b=10
print(a==b) # returns True as a,b have same value 10 
print(a is b)
# returns True,
# we usually falsey assume that a =10 a new object . b=10 a new obj created
# but actually when b=10 ,nothing but b is pointed to 10 until value of a or b is changed from 10 

a=[1]
b=[1]
print(a==b)
#returns True as a,b have a list element 1
print(a is b)
#returns False because here two different objs are created when initiated with lists

O1 O2 => compara se o1 e o2 ambos os pontos a mesma localização física na memória (em outras palavras, se eles são mesmo objeto)

o1 => aqui python chamar __cmp do o1 __ (o2) Método == o2, que idealmente deveria compara o valor e retornar Verdadeiro ou Falso. (Em outras palavras, ele compara o valor)

Para as pessoas Java:

  • Em Java, para determinar se duas variáveis ??de cadeia referência a mesma local de memória física usando str1 == str2 . (Chamado objeto identidade, e é escrito em Python como str1 é str2 ).

  • Para comparar os valores de string em Java, usestr1.equals (str2) ; em Python, usar str1 == str2 .

Exemplo:

class A():
    ...:     def __init__(self,a):
    ...:         self.a = a
    ...:     def __repr__(self):
    ...:         return str(self.a)
    ...:     def __cmp__(self, value):
    ...:         print self.a
    ...:         print value.a
    ...:         return cmp(self.a, value.a)

saída Python Shell:

o = A (2) o1 = o

o == o1 2 2 True

O é o1 True

o1 = A (2)

O é o1 False

Se você compará-lo com JavaScript (no entanto, não é recomendado para comparar uma língua vs outro):

  • Use is para comparação rigorosa. Javascript equivalente (===)
  • Use == para comparação de igualdade.

Enquanto todas essas respostas que dependem da implementação de comparação ponteiro objeção vs comparação de valor provavelmente correta, há uma razão mais profunda sintática para usar is para determinar se um valor variável é None (em lógica booleana, muitas vezes representado como NULL).

No banco de dados relacional e outros sistemas lógicos, NULL implica que o valor real é "desconhecido". Assim, o xx == NULL expressão lógica deve sempre avaliar a NULL si, como é impossível saber sempre se xx, qualquer valor que possa ter, é o mesmo que o valor desconhecido. Em linguagens de programação que aderem mais estritamente as regras de lógica booleana, xx == NULL (ou xx == None Pythonically) avalia corretamente para NULL, e devem ser fornecidos meios alternativos para determinar se um valor variável é NULL. Python é um valor aberrante, a este respeito, devido à natureza unitária do objecto de referência para None. Mas, para clareza e correção lógica, usando o operador Python comparação is parece-me muita prática mais sólida.

Sim, há uma diferença entre ambos.

  • '==' : compara objeto por valor.
  • 'em' :. Compara objeto por referência

    a = [1,2,3]  
    b = a # both pointing to same object (memory location)
    
    a == b:  
    True  
    a in b:   
    True  #because a and b are pointing to same object
    

Agora, vamos considerar este caso:

a = [1,2,3]
b = list(a)  # creating copy of object a

a == b:  
True  # as values are same
a in b:   
False  # because they are pointing to different object.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top