Треки
/
Python
Python
/
Салабус
/
Порівняння
По

Порівняння у Python

7 вправ

Про концепцію Порівняння

Оператор порівняння у Python (який ще називають оператором відношення) бере значення двох операндів і повертає булеве значення (англ. Boolean) True або False залежно від того, виконується умова comparison чи ні.

У таблиці нижче наведено найпоширеніші оператори порівняння в Python:

Оператор Операція Опис
> «більше ніж» a > b є True, якщо a строго більше за b за значенням
< «менше ніж» a < b є True, якщо a строго менше за b за значенням
== «дорівнює» a == b є True, якщо a строго дорівнює b за значенням
>= «більше або дорівнює» a >= b є True, якщо a > b АБО a == b за значенням
<= «менше або дорівнює» a <= b є True, якщо a < b або a == b за значенням
!= «не дорівнює» a != b є True, якщо a == b є False
is «ідентичність» a is b є True, якщо і тільки якщо a і b - той самий обʼєкт
is not «заперечена ідентичність» a is not b є True, якщо і тільки якщо a і b не є тим самим обʼєктом
in «перевірка входження» a in b є True, якщо a є членом, підмножиною або елементом b
not in «заперечна перевірка входження» a not in b є True, якщо a не є членом, підмножиною або елементом b

Усі вони мають однаковий пріоритет (вищий, ніж у булевих операцій, але нижчий, ніж в арифметичних чи порозрядних операцій).

Порівняння між різними типами даних

Обʼєкти різних типів (крім числових типів) типово ніколи не вважаються рівними. Неідентичні екземпляри class також не вважаються рівними, якщо тільки class не визначає спеціальних методів розширеного порівняння, які змінюють типову поведінку порівняння object. Щоб дізнатися (набагато) більше подробиць, можна прочитати розділ Порівняння значень у документації Python.

Числові типи (переважно) є винятком із цього правила збігу типів. integer може вважатися рівним float (а octal - рівним hexadecimal), якщо тільки типи можна неявно звести один до одного для порівняння.

Для інших числових типів (комплексних чисел, десяткових чисел, дробів) оператори порівняння визначено там, де вони «мають сенс» (де неявне зведення не змінює результату), але вони викидають TypeError, якщо відповідні обʼєкти не можна точно звести для порівняння. Докладніше про правила, які Python застосовує для числового зведення, можна прочитати в розділі арифметичні зведення у документації 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

Будь-яке порівняння числа з типом NaN (не число) за порядком дає False. Дещо заплутаний побічний ефект визначення NaN у Python полягає в тому, що NaN ніколи не вважається рівним NaN. Якщо цікаво, чому в Python NaN визначили саме так, можна почитати цю публікацію на Stack Overflow про NaN про ухвалення міжнародного стандарту.

>>> x = float('NaN')

>>> 3 < x
False

>>> x < 3
False

# NaN never compares equal to NaN
>>> x == x
False

Порівняння рядків

Рядки тексту (англ. string) (str) порівнюються лексикографічно за їхніми окремими кодовими позиціями Unicode (це результат передавання кожної кодової позиції зі str до вбудованої функції ord(), яка повертає int). Якщо всі кодові позиції в обох рядках тексту збігаються і розташовані в однаковому порядку, ці два рядки тексту вважаються рівними. Порівняння виконується попарно: перша з першою, друга з другою тощо. У Python 3.x str і bytes не можна безпосередньо звести одне до одного чи порівняти.

>>> '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)

Порівняння контейнерних типів даних

Контейнерні типи даних (lists, tuples, sets, dicts тощо) також порівнюються лексикографічно: вони рівні, якщо обидва контейнери містять однакові дані і належать до однакових типів даних (а у випадку lists і tuples ще й мають однаковий порядок), і нерівні в іншому разі.

>>> [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

Ланцюгове порівняння

Оператори порівняння можна поєднувати в ланцюжок довільно. Зауважмо, що обчислення виразу відбувається від left до right. Наприклад, x < y <= z еквівалентний x < y and y <= z, окрім того, що y обчислюється лише один раз. В обох випадках z зовсім не обчислюється, коли x < y виявляється False. Це часто називають short-circuit evaluation: обчислення припиняється, якщо значення істинності виразу вже визначено.

Short circuiting підтримують різні булеві оператори, функції, а також ланцюгове порівняння в Python. На відміну від багатьох інших мов програмування, зокрема C, C++, C# і Java, ланцюгові вирази на кшталт a < b < c у Python мають звичне математичне тлумачення і пріоритет.

>>> x = 2
>>> y = 5
>>> z = 10

>>> x < y < z
True

>>> x < y > z
False

>>> x > y < z
False

Порівняння ідентичності

Оператори is і is not перевіряють ідентичність обʼєкта, а не його значення. Ідентичність обʼєкта ніколи не змінюється після створення, і її можна дізнатися за допомогою функції id().

<apple> is <orange> дає True тоді і тільки тоді, коли id(<apple>) == id(<orange>). <apple> is not <orange> дає протилежний результат.

Через те що None і NotImplemented існують в єдиному екземплярі, їх завжди слід порівнювати з обʼєктами за допомогою is і is not. Докладніше про цю конвенцію можна прочитати в довідці Python про порівняння значень і в PEP8.


# 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

Порівняння належності

Оператори in і not in перевіряють належність. <fish> in <soup> дає True, якщо <fish> є членом <soup> (якщо <fish> є підмножиною <soup> або міститься в ній), і False в іншому разі. <fish> not in <soup> повертає заперечення, тобто протилежність до <fish> in <soup>.

Для типів рядків тексту й байтів <name> in <fullname> є True тоді й тільки тоді, коли <name> є підрядком <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

Поведінку порівняння обʼєктів можна налаштувати, реалізувавши rich comparison methods. Більше інформації можна знайти в підручнику Python: класи, у Python Classes and Magic Methods (Dan Bader) і в Назви спеціальних методів.

Редагувати через GitHub Посилання відкривається в новому вікні або вкладці

Вивчити концепцію Порівняння

Практика заблокована

Розблокуйте ще 4 вправи, щоб практикувати концепцію Порівняння