Как сравнить 3 числа в python
Перейти к содержимому

Как сравнить 3 числа в python

  • автор:

Как сравнить 3 числа?

Их значения задаются по ходу выполнения программы. А потом надо эти значения сравнить, чтобы найти наименьшее, а именно:

// сравниваем числа if (smallest == a) < . >else if (smallest == b) < . >else if (smallest == c)

Самое первое, что приходит в голову — связка if/else. Но даже с тремя числами такая связка будет весьма длинная, что не очень удобно. И что хуже — два из трёх чисел могут быть и равными, что неудобно, особенно если это будут два наименьших числа. Не подскажете, как коротко и грамотно оформить такое сравнение? Ещё лучше, если это обернуть в функцию вида

Операции сравнения в Python, цепочки сравнений

В Python есть шесть операций сравнения. Все они имеют одинаковый приоритет, который выше, чем у логических операций.

Разрешенные операции сравнения:

  • x < y - строго x меньше y ,
  • x
  • x > y — строго x больше y ,
  • x >= y — x больше или равно y ,
  • x == y — x равно y ,
  • x != y — x не равно y .

Сравнения могут быть связаны произвольно и записаны в цепочки сравнений, в которых для соединения сравнений используются неявные логические операторы and .

x  y  z # эквивалентно x  y and y  z 
a  b  c  d # эквивалентно a  b and b  c and c  d 

В такой форме сравнения легче читаются, и каждое подвыражение вычисляется по крайней мере один раз.

Объекты разных типов, за исключением различных числовых типов, никогда не будут равными.

Оператор == всегда определен, но для некоторых типов объектов, например объектов класса, эквивалентен оператору идентичности is .

Операторы < , и >= применяются только там, где они имеют смысл, например они вызывают исключение TypeError , когда один из аргументов является комплексным числом.

Неидентичные экземпляры класса обычно при сравнении будут неравны, если только класс не определяет метод __eq__() .

Экземпляры класса не могут быть упорядочены относительно других экземпляров того же класса или других типов объектов, если класс не определяет достаточное количество методов __lt__() , __le__() , __gt__() и __ge__() . В общем случае определение методов __lt__() и __eq__() для этих целей бывает достаточно.

Важно! Числа типа float не являются десятичными дробями (decimal.Decimal) и используют двоичную арифметику, поэтому иногда выражения могут вычисляться с ничтожно малыми погрешностями. Из-за этих погрешностей операции сравнения работают не так как ожидается.

>>> 0.8 - 0.5 == 0.3 # False >>> 0.8 - 0.5 - 0.3 == 0 # False >>> 0.8 - 0.5 - 0.3 # 5.551115123125783e-17 >>> from decimal import Decimal >>> Decimal('0.8') - Decimal('0.5') - Decimal('0.3') == 0 # True >>> Decimal('0.8') - Decimal('0.5') - Decimal('0.3') # Decimal('0.0') 

Поведение встроенных типов в операциях сравнения:

  • Числа встроенных числовых типов int , float , complex и стандартных библиотечных типов fractions.Fraction и decimal.Decimal можно сравнивать внутри и между их типами, с ограничением, что комплексные числа не поддерживают сравнение порядка. В пределах задействованных типов они сравнивают математически (алгоритмически) правильно без потери точности. Нечисловые значения float(‘NaN’) и decimal.Decimal(‘NaN’) являются особыми. Любое упорядоченное сравнение числа с нечисловым значением неверно. Нечисловые значения не равны самим себе. Например, если x = float(‘NaN’) , 3 < x , x < 3 и x == x все ложны, а x! = X истинно. Это поведение соответствует стандарту IEEE 754.
  • None и NotImplemented являются одиночными. PEP 8 советует, что сравнения для одиночных экземпляров всегда должны выполняться с использованием или нет, а не с операторами равенства.
  • Двоичные последовательности (экземпляры bytes или bytearray ) можно сравнивать внутри и между их типами. Они сравнивают лексикографически, используя числовые значения своих элементов.
  • Строки (экземпляры str ) сравниваются лексикографически с использованием числовых кодовых точек Unicode (результат встроенной функции ord() ) их символов.

Строки и двоичные последовательности напрямую сравнивать нельзя.

  • Чтобы две коллекции были равными, они должны быть одного типа, иметь одинаковую длину и каждая пара соответствующих элементов должна быть равной. Например [1,2] == (1,2) ложно, потому что типы последовательностей разные.
  • Коллекции, поддерживающие сравнение порядка (сортировку), упорядочиваются также, как их первые неравные элементы, например [1,2, x]

Подводные камни (ловушки цепочек сравнения).

Несмотря на то, что цепочки сравнения выглядят очень разумно, есть пара подводных камней, на которые необходимо обратить внимание.

Нетранзитивные операторы.

Чтобы проверить, совпадают ли a , b и c , можно использовать цепочку сравнения a == b == c . А как проверить, ВСЕ ли они разные? Первое, что приходит в голову — это a != b != c , и попадаем в первую ловушку!

>>> a = c = 1 >>> b = 2 >>> a != b != c # True 

Но это не так. Они не все разные, ведь a == c . Проблема здесь в том, что a != b != c — это a != b and b != c , т.е. проверяет, что b отличается от a и от c , но ничего не говорит о том, как связаны a и c .

С математической точки зрения, != не является транзитивным, т. е. знание того, как a относится к b , и знание того, как b относится к c , не говорит о том, как a относится к c . Что касается транзитивного примера, можно взять оператор равенства == . Если a == b and b == c , то также верно, что a == c .

Непостоянное значение в выражении.

Если b содержит что-то непостоянное или выражение с побочными эффектами, то эти два выражения не эквивалентны.

Этот пример показывает разницу в количестве оценок значения в середине выражения:

def f(): print("run") return 3 >>> 1  f()  5 # run # True >>> 1  f() and f()  5 # run # run # True 
lst = [-2, 2] def f(): global lst lst = lst[::-1] return lst[0] >>> 1  f() and f()  0 # True >>> 1  f()  0 # False 

Синтаксис lst[::-1] — это срез, который переворачивает список.

Плохо читаемые цепочки сравнения.

Цепочки сравнения выглядят действительно естественно, но в некоторых конкретных случаях она не так хороша. Это довольно субъективный вопрос, но лучше избегать цепочки, в которых операторы не «выровнены«, например:

Можно утверждать, например, что a < b >c читается как «проверим, b больше, чем a и c ?«, но лучше эту цепочку записать так max(a, c) < b или b >max(a, c) .

Есть некоторые другие цепочки, которые просто сбивают с толку:

В Python операторы is , is not , in и not in являются операторами сравнения, следовательно их также можно связать с другими операторами. Это создает странные ситуации, такие как:

>>> a = 3 >>> lst = [3, 5] >>> a in lst == True # False 

Примеры использования цепочек сравнения.

>>> a = 1 >>> b = 2 >>> c = 3 >>> a  b  c # True 

Другой пример использования — когда необходимо убедиться, что все три значения одинаковы:

>>> a = b = 1 >>> c = 2 >>> if a == b == c: . print("все равны") . else: . print("некоторые отличаются") # некоторые отличаются >>> c = 1 >>> if a == b == c: . print("все равны") . else: . print("некоторые отличаются") # все равны 

На самом деле можно связать произвольное количество операторов сравнения в цепочку? Например, a == b == c == d == e проверяет, совпадают ли все пять переменных, в то время как a < b < c < d < e проверяет, есть ли строго возрастающая последовательность.

По известным результатам сравнения трех чисел расположить их в порядке возрастания

Сравнения
Про три числа (обозначенных a, b, c) известны все результаты сравнения их друг с другом. Требуется расположить эти числа в порядке возрастания.

Вводятся три строки. В первой записан результат сравнения между собой чисел a и b в следующем формате. Первый символ — всегда a, третий символ — b (соответствующие маленькие латинские буквы), а между ними записан один из символов >, < или =. Во второй строке в таком же формате записан результат сравнения a и с (первый символ всегда a, третий — c), а в третьей строке — результат сравнения b и c (первый символ всегда b, третий — c). Гарантируется, что входные данные не противоречивы.

Выведите символы a, b, c в порядке величины соответствующих им чисел — каждое следующее число должно быть больше либо равно предыдущему. Если два числа равны между собой, соответствующие переменные могут быть выведены в любом порядке. Символы должны быть выведены в одной строке без пробелов и других разделителей.

Если вариантов ответа несколько — не нужно выводить их все, ваша программа должна вывести ровно один вариант ответа.

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

10 чисел расположить в порядке возрастания
Нужно составить задачу, чтобы в итоге 10 чисел располагались в порядке возрастания!

Если сумма чисел — четная, то расположить эти числа в порядке возрастания
Подскажите: нужно сгенерировать 4 случайных числа и если их сумма — четная, то расположить эти.

Составить прогу расположения трёх чисел в порядке возрастания
Составить прогу расположения трёх чисел(т.е. вводимых с клавиатуры) в порядке возрастания Буду.

Расположить чётные числа массива в порядке возрастания, а нечётные в порядке убывания
Требуется расположить чётные числа в порядке возрастания, а не чётные в порядке убывания.

Операторы сравнения

Эти операторы сравнивают два типа значений, они меньше и больше чем операторы. Для чисел это просто сравнивает числовые значения, чтобы увидеть, что больше:

12 > 4 # True 12 < 4 # False 1 < 4 # True 

Для строк они будут сравниваться лексикографически, что похоже на алфавитный порядок, но не совсем то же самое.

"alpha" < "beta" # True "gamma" >"beta" # True "gamma" < "OMEGA" # False 
"GAMMA" < "OMEGA" # True 

Каждый тип определяет это расчет с < и >операторы по- разному, так что вы должны исследовать , что операторы означают с данным типом перед его использованием.

Не равно

x != y 

Это возвращает True , если x и y не равны и в противном случае возвращает значение False .

12 != 1 # True 12 != '12' # True '12' != '12' # False 

Равно

x == y 

Это выражение , если x и y имеют одинаковое значение и возвращает результат как логическое значение. В целом как тип и значение должны совпадать, так что ИНТ 12 не то же самое , как строка '12' .

12 == 12 # True 12 == 1 # False '12' == '12' # True 'spam' == 'spam' # True 'spam' == 'spam ' # False '12' == 12 # False 

Обратите внимание, что каждый тип должен определять функцию, которая будет использоваться для оценки, если два значения одинаковы. Для встроенных типов эти функции ведут себя так, как вы ожидаете, и просто оценивают вещи, основываясь на том же значении. Однако пользовательские типы можно определить тестирование равенства , как бы они ни хотели, в том числе всегда возвращаются True или всегда возвращаются False .

Сравнение цепей

Вы можете сравнить несколько элементов с несколькими операторами сравнения с помощью цепочки сравнения. Например

x > y > z 

это просто краткая форма:

x > y and y > z 

Это позволит оценить, True , только если оба сравнения True .

a OP b OP c OP d . 

Где OP представляет один из нескольких операций сравнения , которые можно использовать, а буквы представляют собой произвольные действительные выражения.

Стиль

Нет теоретического ограничения на количество элементов и операций сравнения, если вы используете правильный синтаксис:

1 > -1 < 2 >0.5 < 100 != 24 

Вышеприведенные возвращает True , если каждое сравнение возвращает True .Тем не менее, использование замысловатой цепочки не очень хороший стиль. Хорошая цепочка будет «направленной», не более сложной, чем

1 > x > -4 > y != 8 

Побочные эффекты

Как только одно сравнение возвращает значение False , выражение сразу вычисляет значение False , пропуская все остальные сравнения.

Отметим , что выражение exp в a > exp > b будет оцениваться только один раз, в то время как в случае

a > exp and exp > b 

exp будет вычисляться дважды , если a > exp верно.

Сравнение по `is` vs` == `

Типичная ошибка является запутанными операторы сравнения равенства is и == .

a == b сравнивает значение и a b .

a is b сравнит тождества и a b .

a = 'Python is fun!' b = 'Python is fun!' a == b # returns True a is b # returns False a = [1, 2, 3, 4, 5] b = a # b references a a == b # True a is b # True b = a[:] # b now references a copy of a a == b # True a is b # False [!!] 

В принципе, is можно рассматривать как сокращение для id(a) == id(b) .

Помимо этого, существуют особенности среды выполнения, которые еще больше усложняют ситуацию. Короткие строки и небольшие целые числа будут возвращать True , по сравнению с is , из - за машины Python пытается использовать меньше памяти для одинаковых объектов.

a = 'short' b = 'short' c = 5 d = 5 a is b # True c is d # True 

Но более длинные строки и большие целые числа будут храниться отдельно.

a = 'not so short' b = 'not so short' c = 1000 d = 1000 a is b # False c is d # False 

Вы должны использовать is , чтобы проверить на None :

if myvar is not None: # not None pass if myvar is None: # None pass 

Применение по is является проверка на «дозорных» (то есть уникальный объект).

sentinel = object() def myfunc(var=sentinel): if var is sentinel: # value wasn’t provided pass else: # value was provided pass 

Сравнение объектов

Для сравнения равенства пользовательских классов, вы можете переопределить == и != Определяя __eq__ и __ne__ методу. Вы также можете переопределить __lt__ ( < ), __le__ ( ), и __ge__ ( > ). Обратите внимание , что вам нужно только переопределить два метода сравнения, и Python может справиться с остальным ( == таким же , как not < и not >, и т.д.)

class Foo(object): def __init__(self, item): self.my_item = item def __eq__(self, other): return self.my_item == other.my_item a = Foo(5) b = Foo(5) a == b # True a != b # False a is b # False 

Заметим , что это простое сравнение предполагает , что other объект (объект сравнивается с) имеет тот же тип объекта. Сравнение с другим типом приведет к ошибке:

class Bar(object): def __init__(self, item): self.other_item = item def __eq__(self, other): return self.other_item == other.other_item def __ne__(self, other): return self.other_item != other.other_item c = Bar(5) a == c # throws AttributeError: 'Foo' object has no attribute 'other_item' 

Проверка isinstance() или аналогичный поможет предотвратить это (если это необходимо).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *