“Х не в у” або “не х в у”


97

Під час тестування на членство ми можемо використовувати:

x not in y

Або як варіант:

not x in y

Для цього виразу може бути багато можливих контекстів залежно від xта y. Наприклад, це може бути для перевірки підрядків, членства в списку, існування ключа дикту.

  • Чи завжди дві форми еквівалентні?
  • Чи є бажаний синтаксис?

Відповіді:


112

Вони завжди дають однаковий результат.

Насправді, not 'ham' in 'spam and eggs'здається, спеціальний корпус виконує одну операцію "не в", а не операцію "в", а потім заперечує результат:

>>> import dis

>>> def notin():
    'ham' not in 'spam and eggs'
>>> dis.dis(notin)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not_in():
    not 'ham' in 'spam and eggs'
>>> dis.dis(not_in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not__in():
    not ('ham' in 'spam and eggs')
>>> dis.dis(not__in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

>>> def noteq():
    not 'ham' == 'spam and eggs'
>>> dis.dis(noteq)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 POP_TOP             
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE      

Спочатку я думав, що вони завжди дають однаковий результат, але це саме notпо собі є просто логічним оператором заперечення з низьким пріоритетом, до якого можна застосувати a in bтак само легко, як до будь-якого іншого булевого виразу, тоді як not inдля зручності та ясності це окремий оператор .

Розбирання вище було показовим! Здається, хоча notочевидно є логічним оператором заперечення, форма not a in bмає особливий корпус, так що насправді не використовується загальний оператор. Це робить not a in bбуквально такий самий вираз a not in b, а не просто вираз, що призводить до того самого значення.


4
Майте на увазі, що це лише деталі реалізації. Я навіть не можу згадати про це not x in xsв документації.
phant0m

1
@ phant0m Абсолютно; як ви повинні думати про not x in xsIS not (x in xs). Але той факт, що він реалізований шляхом його синтаксичного аналізу на точно такий самий байт-код, що x not in xsдуже чітко показує, що вони повинні бути завжди однаковими, на відміну від таких речей, як not x == yvs, x != yякі повинні давати однаковий результат, але не повинні (залежно від реалізації __eq__і __ne__залучені).
Бен,

11
Ви зіткнулися з оптимізацією очей CPython ; оптимізація часу компіляції, яку інші реалізації Python, такі як Jython та IronPython, можуть ігнорувати або копіювати (це не є частиною специфікації мови).
Мартін Пітерс

15

  1. Ні, різниці немає.

    Оператор not inвизначений таким, що має обернене справжнє значення in.

    - Документація на Python

  2. Я вважаю, що not inце кращий варіант, оскільки він є більш очевидним, і вони додали для цього особливий випадок.



3

Інші вже чітко дали зрозуміти, що ці два твердження є, до досить низького рівня, еквівалентними.

Однак я не думаю, що ще хтось наголосив настільки, що, оскільки це залишає вибір за вами, ви повинні

виберіть форму, яка робить ваш код максимально читабельним.

І не обов'язково читаються як можна кому - або , навіть якщо це, звичайно, хороша річ , щоб прагнути. Ні, переконайтесь, що код для вас максимально читабельним , оскільки саме ви найімовірніше повернетесь до цього коду пізніше та спробуєте його прочитати.


Якщо ви працюєте у великій команді або над кодом, який певний час може бути недоторканим, швидше за все, хтось інший повинен його підтримувати.
Томмі Герберт


1

Синтаксично це одне і те ж твердження. Я швидко сказав би, що 'ham' not in 'spam and eggs'передає чіткіші наміри, але я бачив код і сценарії, в яких not 'ham' in 'spam and eggs'передає більш чітке значення, ніж інші.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.