O Python oferece os seguintes operadores de comparação básicos:
| 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 a e b não forem o mesmo objeto
|
in |
"teste de contenção" |
a in b é True se a for membro, subconjunto ou elemento de b
|
not in |
"teste de contenção 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 especiais de comparação avançada que personalizam o comportamento padrão de comparação de object.
A personalização por meio de rich comparisons será abordada em um exercício seguinte.
Para obter (muito) mais detalhes sobre esse tópico, 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 da biblioteca padrão do Python (complex, decimal, fractions), os operadores de comparação são definidos onde "fazem sentido" (onde a conversão implícita não altera 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 é igual a NaN na comparação.
>>> x = float('NaN')
>>> 3 < x
False
>>> x < 3
False
# NaN never compares equal to NaN
>>> x == x
False
Diferentemente dos números, 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 de forma "aos pares": primeiro com primeiro, segundo com segundo, e assim por diante.
No Python 3.x, str e bytes não podem ser convertidos/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 operadores de comparação podem ser encadeados arbitrariamente, ou seja, podem ser usados em qualquer combinação e com qualquer comprimento.
Observe que a avaliação de uma expressão acontece de left para right.
Como 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 é considerado False.
Isso costuma ser chamado de short-circuit evaluation: a avaliação para se o valor de verdade 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.
Diferentemente 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 convencional e precedência.
>>> 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 valor do objeto.
A identidade de um objeto nunca muda após a criação 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> produz o inverso.
Devido ao seu status de singleton, None e NotImplemented devem sempre ser comparados a 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.
>>> 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 a pertinência.
<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
Neste exercício, você vai implementar algumas regras do Blackjack, como a forma de jogar e pontuar.
Observação: neste exercício, A significa ás, J significa valete, Q significa dama, e K significa rei.
Os coringas são descartados.
Assume-se um baralho padrão de 52 cartas com naipes franceses, mas na maioria das versões, vários baralhos são embaralhados juntos para o jogo.
No Blackjack, fica a critério de cada jogador se um ás vale 1 ou 11 pontos (mais sobre isso depois).
As cartas figuras (J, Q, K) valem 10 pontos, e qualquer outra carta vale o seu valor "pip" (numérico).
Defina a função value_of_card(<card>) com o parâmetro card.
A função deve retornar o valor numérico da string de carta recebida.
Como um ás pode assumir vários valores (1 ou 11), por enquanto essa função deve fixar o valor de uma carta ás em 1.
Mais adiante, você vai implementar uma função para determinar o valor de uma carta ás, dada uma mão existente.
>>> value_of_card('K')
10
>>> value_of_card('4')
4
>>> value_of_card('A')
1
Defina a função higher_card(<card_one>, <card_two>) com os parâmetros card_one e card_two.
Para fins de pontuação, o valor de J, Q ou K é 10.
A função deve retornar qual carta tem o valor mais alto para a pontuação.
Se as duas cartas tiverem o mesmo valor, retorne as duas.
Retornar as duas cartas pode ser feito usando uma vírgula na instrução return:
# Using a comma in a return creates a Tuple. Tuples will be covered in a later exercise.
>>> def returning_two_values(value_one, value_two):
return value_one, value_two
>>> returning_two_values('K', '3')
('K', '3')
Um ás pode assumir vários valores, então vamos fixar as cartas A em um valor de 1 para esta tarefa.
>>> higher_card('K', '10')
('K', '10')
>>> higher_card('4', '6')
'6'
>>> higher_card('K', 'A')
'K'
Como mencionado antes, um ás pode valer tanto 1 quanto 11 pontos. Os jogadores tentam chegar o mais perto possível de 21 pontos, sem passar de 21 ("estourar").
Defina a função value_of_ace(<card_one>, <card_two>) com os parâmetros card_one e card_two, que são um par de cartas já na mão antes de receber uma carta ás.
Sua função terá que decidir se o próximo ás vai receber o valor 1 ou o valor 11, e retornar esse valor.
Lembre-se: o valor da mão com o ás precisa ser o mais alto possível sem passar de 21.
Dica: se já tivermos um ás na mão, o valor do próximo ás seria 1.
>>> value_of_ace('6', 'K')
1
>>> value_of_ace('7', '3')
11
Se um jogador receber um ás (A) e uma carta de dez (10, K, Q ou J) como suas duas primeiras cartas, ele terá uma pontuação de 21.
Isso é conhecido como uma mão de blackjack.
Defina a função is_blackjack(<card_one>, <card_two>) com os parâmetros card_one e card_two, que são um par de cartas.
Determine se a mão de duas cartas é um blackjack, e retorne o Boolean True se for, False caso contrário.
Observação: o cálculo da pontuação pode ser feito de várias formas. Mas, se possível, gostaríamos que você verificasse se há um ás e uma carta de dez na mão (ou em uma certa posição), em vez de somar os valores da mão.
>>> is_blackjack('A', 'K')
True
>>> is_blackjack('10', '9')
False
Se as duas primeiras cartas de uma mão tiverem o mesmo valor (por exemplo, dois seis ou um Q e um K), um jogador pode escolher tratá-las como duas mãos separadas.
Isso é conhecido como "dividir pares".
Defina a função can_split_pairs(<card_one>, <card_two>) com os parâmetros card_one e card_two, que são um par de cartas.
Determine se essa mão de duas cartas pode ser dividida em dois pares.
Se a mão puder ser dividida, retorne o Boolean True; caso contrário, retorne False
>>> can_split_pairs('Q', 'K')
True
>>> can_split_pairs('10', 'A')
False
Quando as duas cartas iniciais distribuídas somam 9, 10 ou 11 pontos, o jogador pode fazer uma aposta adicional igual à aposta original. Isso é conhecido como "dobrar a aposta".
Defina a função can_double_down(<card_one>, <card_two>) com os parâmetros card_one e card_two, que são um par de cartas.
Determine se a mão de duas cartas pode ser "dobrada", e retorne o Boolean True se puder, False caso contrário.
>>> can_double_down('A', '9')
True
>>> can_double_down('10', '2')
False
Crie sua conta no Exercism para aprender e dominar Python com 17 conceitos146 exercícios e mentoria humana de verdade, tudo de graça.