Что по сути делает синтаксис Python «in»?

Скажем, у меня есть произвольный контейнер и запрос, есть ли в нем элемент, см. ниже.

D = {(1, 2): "whatever"}
if (2, 1) in D:
    print( "Impossible" ) 

Что на самом деле происходит с базовым кодом? вызывается ли какая-либо конкретная функция-член, такая как find()?

Более того, могу ли я использовать собственный cmp/хеш? скажем, если я хотел бы сравнить только появление каждого числа в ключе кортежа, как показано в фрагменте кода, что я могу сделать, чтобы добиться этого?

D = {(1, 2, 1): "whatever"}
if (2, 1, 1) in D:
    print( "As expected" ) # How to make it happen?

Официальный документ Py будет очень признателен. Я предполагаю, что это довольно фундаментальная информация, но нигде не могу найти официального вступления.

Большое спасибо за быстрый ответ и помощь. Означает ли это, что невозможно настроить встроенный контейнер, а можно только наследовать или инкапсулировать его?

PkDrew 24.08.2024 11:12

Невозможно напрямую настроить то, что делает любой метод любого встроенного типа. __contains__() в этом плане ничего особенного. Например. нет возможности напрямую изменить то, что делает int.__add__(). В CPython вам потребуется отредактировать исходный код C, реализующий этот метод, и перекомпилировать.

Tim Peters 24.08.2024 11:36

Понял, большое спасибо за ответ еще раз.

PkDrew 24.08.2024 11:37

Вы хотите сказать, что хотели бы, чтобы (2,1,1) было эквивалентно (1,2,1)? Если да, реализуйте __contains__ и сравните в нем отсортированные значения.

SIGHUP 24.08.2024 11:39
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это определено в разделе «Справочник по языку» 6.10.2. Операции по проверке членства; в частности:

Все встроенные последовательности и типы наборов поддерживают это, а также словарь, для которого проверяется, имеет ли словарь заданный ключ. Для таких типов контейнеров, как список, кортеж, набор, замороженный набор, dict или Collections.deque, выражение x in y эквивалентно any(x is e or x == e for e in y).

[…] Для пользовательских классов, определяющих метод __contains__(), x in y возвращает True, если y.__contains__(x) возвращает истинное значение, и False в противном случае. […]

Под одеялом x in y вызывает y.__contains__(x). Таким образом, поведение полностью зависит от того, как type(y) реализует специальный __contains__ метод.

>>> class X:
...     def __contains__(self, i):
...         if i == 4:
...             return True
...         elif i < 0:
...             return "hamburger"
...         else:
...             return False
...
>>> 3 in X()
False
>>> 4 in X()
True
>>> -4 in X()
True

Последнее может быть удивительным. Оно не возвращается "hamburger", но под покровом накладывается другой слой bool() на то, что __contains__() на самом деле возвращается.

>>> bool("hamburger")
True

Другие вопросы по теме