Um operador de comparação em Python (também chamado de operador relacional do Python) examina os valores de dois operandos e retorna um Boolean True ou False conforme a condição comparison seja satisfeita ou não.
A tabela abaixo mostra os operadores de comparação mais comuns do Python:
| Operador | Operação | Descrição |
|---|---|---|
> |
"maior que" |
a > b é True se a for estritamente maior em valor que b
|
< |
"menor que" |
a < b é True se a for estritamente menor em valor que b
|
== |
"igual a" |
a == b é True se a for estritamente igual a b em valor |
>= |
"maior ou igual a" |
a >= b é True se a > b OU a == b em valor |
<= |
"menor ou igual a" |
a <= b é True se a < b ou a == b em valor |
!= |
"diferente de" |
a != b é True se a == b for False
|
is |
"identidade" |
a is b é True se e somente se a e b forem o mesmo objeto
|
is not |
"identidade negada" |
a is not b é True se e somente se a e b não forem o mesmo objeto
|
in |
"teste de pertencimento" |
a in b é True se a for membro, subconjunto ou elemento de b
|
not in |
"teste de pertencimento negado" |
a not in b é True se a não for membro, subconjunto ou elemento de b
|
Todos eles têm a mesma prioridade (que é maior que a das operações Boolean, mas menor que a das operações aritméticas ou bit a bit).
Objetos de tipos diferentes (exceto tipos numéricos) nunca são considerados iguais por padrão.
Instâncias não idênticas de uma class também não serão consideradas iguais, a menos que a class defina métodos de comparação rich especiais que personalizam o comportamento padrão de comparação de object.
Para (muito) mais detalhes, consulte Comparações de valores na documentação do Python.
Os tipos numéricos são (em sua maioria) uma exceção a essa regra de correspondência de tipos.
Um integer pode ser considerado igual a um float (ou um octal igual a um hexadecimal), desde que os tipos possam ser convertidos implicitamente para a comparação.
Para os outros tipos numéricos (complexos, decimais, frações), os operadores de comparação são definidos onde "fazem sentido" (onde a conversão implícita não muda o resultado), mas lançam um TypeError se os objetos subjacentes não puderem ser convertidos com precisão para a comparação.
Para mais informações sobre as regras que o Python usa para conversão numérica, consulte conversões aritméticas na documentação do Python.
>>> import fractions
# A string cannot be converted to an int.
>>> 17 == '17'
False
# An int can be converted to float for comparison.
>>> 17 == 17.0
True
# The fraction 6/3 can be converted to the int 2
# The int 2 can be converted to 0b10 in binary.
>>> 6/3 == 0b10
True
# An int can be converted to a complex
# number with a 0 imaginary part.
>>> 17 == complex(17)
True
# The fraction 2/5 can be converted to the float 0.4
>>> 0.4 == 2/5
True
>>> complex(2/5, 1/2) == complex(0.4, 0.5)
True
Qualquer comparação ordenada de um número com um tipo NaN (não é um número) é False.
Um efeito colateral confuso da definição de NaN do Python é que NaN nunca é considerado igual a NaN.
Se você ficou curioso sobre por que NaN foi definido dessa forma no Python, este post do Stack Overflow sobre NaN sobre a definição do padrão internacional é uma leitura interessante.
>>> x = float('NaN')
>>> 3 < x
False
>>> x < 3
False
# NaN never compares equal to NaN
>>> x == x
False
As strings (str) são comparadas lexicograficamente, usando seus pontos de código Unicode individuais (o resultado de passar cada ponto de código da str para a função embutida ord(), que retorna um int).
Se todos os pontos de código das duas strings coincidirem e estiverem na mesma ordem, as duas strings serão consideradas iguais.
Essa comparação é feita em pares: primeiro com primeiro, segundo com segundo, etc.
No Python 3.x, str e bytes não podem ser convertidos nem comparados diretamente.
>>> 'Python' > 'Rust'
False
>>> 'Python' > 'JavaScript'
True
# Examples with Mandarin.
# hello < goodbye
>>> '你好' < '再见'
True
# ord() of first characters
>>> ord('你'), ord('再')
(20320, 20877)
# ord() of second characters
>>> ord('好'), ord('见')
(22909, 35265)
# And with Korean words.
# Pretty < beautiful.
>>> '예쁜' < '아름다운'
False
>>> ord('예'), ord('아')
(50696, 50500)
Os tipos de dados container (lists, tuples, sets, dicts, etc.) também são comparados lexicograficamente: eles são iguais se ambos os containers tiverem os mesmos dados e os mesmos tipos de dados (no caso de lists e tuples, também precisam ter a mesma ordenação); caso contrário, são diferentes.
>>> [1, 2] == [1, 2]
True
# But if the data is not in the same order, they are not equal.
>>> [2, 1] == [1, 2]
False
# The same holds true for tuples
>>> (3,4,5) == (5,4,3)
False
# Length is also compared
>>> [1, 2] < [1, 2, 3]
True
# Comparing dicts
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 18}
False
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 19}
True
Os operadores de comparação podem ser encadeados de forma arbitrária.
Observe que a avaliação de uma expressão acontece da left para a right.
Por exemplo, x < y <= z é equivalente a x < y and y <= z, exceto que y é avaliado apenas uma vez.
Nos dois casos, z não é avaliado de forma alguma quando x < y resulta em False.
Isso costuma ser chamado de short-circuit evaluation: a avaliação para se o valor lógico da expressão já tiver sido determinado.
O Short circuiting é suportado por vários operadores Boolean, funções e também pelo encadeamento de comparações no Python.
Ao contrário de muitas outras linguagens de programação, incluindo C, C++, C# e Java, expressões encadeadas como a < b < c no Python têm uma interpretação matemática e uma precedência convencionais.
>>> x = 2
>>> y = 5
>>> z = 10
>>> x < y < z
True
>>> x < y > z
False
>>> x > y < z
False
Os operadores is e is not testam a identidade do objeto, em oposição ao seu valor.
A identidade de um objeto nunca muda depois de criado e pode ser obtida com a função id().
<apple> is <orange> resulta em True se e somente se id(<apple>) == id(<orange>).
<apple> is not <orange> dá o inverso.
Devido ao seu status de singleton, None e NotImplemented sempre devem ser comparados com itens usando is e is not.
Consulte a documentação de referência do Python sobre comparações de valores e o PEP8 para mais detalhes sobre essa convenção.
# A list of favorite numbers.
>>> my_fav_numbers = [1, 2, 3]
>>> your_fav_numbers = my_fav_numbers
>>> my_fav_numbers is your_fav_numbers
True
# The returned id will differ by system and Python version.
>>> id(my_fav_numbers)
4517478208
# your_fav_numbers is only an alias pointing to the original my_fav_numbers object.
# Assigning a new name does not create a new object.
>>> id(your_fav_numbers)
4517478208
>>> my_fav_numbers is not your_fav_numbers
False
>>> my_fav_numbers is not None
True
>>> my_fav_numbers is NotImplemented
False
Os operadores in e not in testam o pertencimento.
<fish> in <soup> resulta em True se <fish> for um membro de <soup> (se <fish> for um subconjunto de <soup> ou estiver contido nele), e resulta em False caso contrário.
<fish> not in <soup> retorna a negação, ou o oposto de <fish> in <soup>.
Para os tipos string e bytes, <name> in <fullname> é True se e somente se <name> for uma substring de <fullname>.
# A set of lucky numbers.
>>> lucky_numbers = {11, 22, 33}
>>> 22 in lucky_numbers
True
>>> 44 in lucky_numbers
False
# A dictionary of employee information.
>>> employee = {'name': 'John Doe', 'id': 67826, 'age': 33, 'title': 'ceo'}
# Checking for the membership of certain keys.
>>> 'age' in employee
True
>>> 33 in employee
False
>>> 'lastname' not in employee
True
# Checking for substring membership
>>> name = 'Super Batman'
>>> 'Bat' in name
True
>>> 'Batwoman' in name
False
O comportamento de comparação dos objetos pode ser personalizado por meio da implementação de rich comparison methods.
Para mais informações, consulte Tutorial do Python: classes, Python Classes and Magic Methods (Dan Bader) e Nomes de métodos especiais.