Еквівалент Python && (логічний-і) в операторі if


828

Ось мій код:

def front_back(a, b):
  # +++your code here+++
  if len(a) % 2 == 0 && len(b) % 2 == 0:
    return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
  else:
    #todo! Not yet done. :P
  return

Я отримую помилку, якщо ІФ умовно.
Що я роблю неправильно?


10
Ясно, що Серхіо хотів дізнатися, чому його код порушено, але я прочитав трохи більше назви питання. Чому б інакше не було доступно? == і! = доступні (але я не знаю, що є, і не є). Чому б не включити цей синтаксис? Особисті переваги?
Physicsmichael

5
@ vgm64: Навіщо включати зайвий синтаксис, який не покращує жодного аспекту?
Конрад Рудольф

27
Мені здається, що інтерпретатору слід, а не роздрукувати криптовалюту "SyntaxError: недійсний синтаксис", - виявити, що користувач використовував, &&і запропонувати їм, що вони можуть andзамість цього використовувати ключове слово . Те саме стосується таких речей, як ++і інші поширені оператори з інших мов.
ArtOfWarfare

3
@physicsmichael "Має бути один, бажано лише один, очевидний спосіб зробити це". import this
Нік Т

3
@KonradRudolph Це абсолютно покращує аспекти мови. Це більш послідовно та інтуїтивно зрозуміло для тих, хто коли-небудь використовував будь-яку іншу мову. той факт, що це питання існує та має стільки трафіку, скільки чітко підкреслює це питання, як загальну точку зору для людей.
jterm

Відповіді:


1469

Ви хотіли б andзамість цього &&.


2
що я повинен зробити для цього: якщо x == 'n' і y == 'a' або y == 'b': <зробити щось> Чи буде це працювати !? @ChristopheD
diffracteD

7
@diffracteD: Використовуйте круглі дужки, якщо ви хочете змінити стандартний пріоритет оператора (про що ви можете дізнатися тут: ibiblio.org/g2swap/byteofpython/read/operator-precedence.html )
ChristopheD

3
Мені подобається , що Девід Titarenco дав вирізати-н-Paste приклад
Alexx Roche

7
Я приїхав сюди після того, як я набрав &&і те, ANDі отримав помилку (не сподіваючись, що пітон захоче слово з малих літер and).
Xeoncross

2
Я думаю , ви повинні використовувати & See: stackoverflow.com/questions/36921951 / ...
user1761806

229

Python використовує andі orумовні умови.

тобто

if foo == 'abc' and bar == 'bac' or zoo == '123':
  # do something

5
Не забувайте, що python також не має (ну, і!)
inspectorG4dget

9
Чи оцінює ваш приклад "(якщо це і це) чи" АБО ", якщо це і (це чи те)"?
Джефф

12
@Jeff Ваш перший шлях. and має вищий пріоритет ніж or.
Buge

1
@Buge це виглядає як "або" вище в таблиці, яку ви пов’язали
Метт

5
@Matt таблиця переходить від найнижчого пріоритету до найвищого. Легше запам'ятати пріоритет, якщо ви вивчали булеву алгебру; "або" є додаванням і "і" є множенням.
Майкл Стройд

48

Я отримую помилку, якщо ІФ умовно. Що я роблю неправильно?

Причина, що ви отримуєте, SyntaxErrorполягає в тому, що &&в Python немає оператора. Точно так же ||і !є недійсним оператори Python.

Деякі оператори, яких ви можете знати з інших мов, мають іншу назву в Python. Логічні оператори &&і ||насправді називаються andі or. Так само !називається оператор логічного заперечення not.

Тож ви могли просто написати:

if len(a) % 2 == 0 and len(b) % 2 == 0:

або навіть:

if not (len(a) % 2 or len(b) % 2):

Деякі додаткові відомості (які можуть бути корисні):

Я підсумував оператор "еквіваленти" у цій таблиці:

+------------------------------+---------------------+
|  Operator (other languages)  |  Operator (Python)  |
+==============================+=====================+
|              &&              |         and         |
+------------------------------+---------------------+
|              ||              |         or          |
+------------------------------+---------------------+
|              !               |         not         |
+------------------------------+---------------------+

Дивіться також документацію Python: 6.11. Булеві операції .

Крім логічних операторів, Python також має бітові / бінарні оператори:

+--------------------+--------------------+
|  Logical operator  |  Bitwise operator  |
+====================+====================+
|        and         |         &          |
+--------------------+--------------------+
|         or         |         |          |
+--------------------+--------------------+

У Python немає бітового заперечення (просто бітовий зворотний оператор ~- але це не еквівалентно not).

Див. Також 6.6. Одинарні арифметичні та бітові / двійкові операції та 6.7. Двійкові арифметичні операції .

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

Щоб показати це, я використовую функцію, яка просто приймає значення, роздруковує його і повертає знову. Це зручно, щоб побачити, що насправді оцінюється через друковані виписки:

>>> def print_and_return(value):
...     print(value)
...     return value

>>> res = print_and_return(False) and print_and_return(True)
False

Як ви бачите, виконується лише одна операція друку, тому Python насправді навіть не дивився на потрібний операнд.

Це не стосується бінарних операторів. Вони завжди оцінюють обидва операнди:

>>> res = print_and_return(False) & print_and_return(True);
False
True

Але якщо першого операнда недостатньо, то, звичайно, оцінюється другий оператор:

>>> res = print_and_return(True) and print_and_return(False);
True
False

Підсумовуючи це ось ще одна таблиця:

+-----------------+-------------------------+
|   Expression    |  Right side evaluated?  |
+=================+=========================+
| `True` and ...  |           Yes           |
+-----------------+-------------------------+
| `False` and ... |           No            |
+-----------------+-------------------------+
|  `True` or ...  |           No            |
+-----------------+-------------------------+
| `False` or ...  |           Yes           |
+-----------------+-------------------------+

TrueІ Falseє те , що bool(left-hand-side)повертається, вони не повинні бути Trueабо Falseвони просто необхідно повернути Trueабо Falseколи boolвикликається на них (1).

Отже, у Псевдокодексі (!) Функції andі orпрацюють так:

def and(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return evaluate(expr2)
    else:
        return left

def or(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return left
    else:
        return evaluate(expr2)

Зауважте, що це псевдо-код, а не код Python. У Python ви не можете створювати функції, викликані andабо orтому, що це ключові слова. Також ніколи не слід використовувати "оцінювати" або if bool(...).

Налаштування поведінки ваших власних занять

Цей неявний boolвиклик може бути використаний для настройки , як ваші класи поводяться з and, orі not.

Щоб показати, як це можна налаштувати, я використовую цей клас, який знову printщось відстежує, що відбувається:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print('__bool__ called on {!r}'.format(self))
        return bool(self.value)

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

Тож давайте подивимося, що відбувається з цим класом у поєднанні з цими операторами:

>>> if Test(True) and Test(False):
...     pass
__bool__ called on Test(True)
__bool__ called on Test(False)

>>> if Test(False) or Test(False):
...     pass
__bool__ called on Test(False)
__bool__ called on Test(False)

>>> if not Test(True):
...     pass
__bool__ called on Test(True)

Якщо у вас немає __bool__методу, Python також перевіряє, чи є у об'єкта __len__метод і чи повертає він значення, що перевищує нуль. Це може бути корисно знати, якщо ви створюєте контейнер послідовностей.

Див. Також 4.1. Тестування істинної цінності .

Масиви та підкласи NumPy

Можливо, трохи виходить за рамки оригінального питання, але якщо ви маєте справу з масивами чи підкласами NumPy (наприклад, серії Pandas або DataFrames), то неявний boolвиклик призведе до виникнення боязні ValueError:

>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

У цих випадках ви можете використовувати логіку та функцію від NumPy, яка виконує елементи and(або or):

>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False,  True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False,  True,  True])

Якщо ви маєте справу лише з булевими масивами, ви також можете використовувати бінарні оператори з NumPy, вони виконують елементарно (але також і двійкові) порівняння:

>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False,  True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False,  True,  True])

(1)

Що boolвиклик операндів повинен повернутися Trueабо Falseне зовсім коректний. Це просто перший операнд, якому потрібно повернути булевий __bool__метод у своєму методі:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return self.value

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)

Це тому, що andфактично повертає перший операнд, якщо перший операнд оцінює, Falseа якщо він оцінює, Trueто він повертає другий операнд:

>>> x1
Test(10)
>>> x2
Test(False)

Так само, orале навпаки:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

Однак якщо ви використовуєте їх у ifзаяві, це ifтакож неявно закликає boolрезультат. Тож ці тонкі бали можуть не бути актуальними для вас.


36

Два коментарі:

  • Використання andі orдля логічних операцій в Python.
  • Використовуйте 4 пробіли для відступу замість 2. Ви будете вдячні пізніше, оскільки ваш код буде виглядати приблизно так само, як і код інших. Див. PEP 8 для отримання більш детальної інформації.

10

Ви використовуєте andтаor виконуєте логічні операції, як у C, C ++. Наче буквально andє &&і orє|| .


Подивіться на цей веселий приклад,

Скажіть, що ви хочете побудувати логічні ворота в Python:

def AND(a,b):
    return (a and b) #using and operator

def OR(a,b):
    return (a or b)  #using or operator

Тепер спробуйте зателефонувати їм:

print AND(False, False)
print OR(True, False)

Це виведе:

False
True

Сподіваюся, це допомагає!


9

Я пішов із чисто математичним рішенням:

def front_back(a, b):
  return a[:(len(a)+1)//2]+b[:(len(b)+1)//2]+a[(len(a)+1)//2:]+b[(len(b)+1)//2:]

7
Це не відповідь на власне питання.
Матвій

5

Можливо, це не найкращий код для цього завдання, але працює -

def front_back(a, b):

 if len(a) % 2 == 0 and len(b) % 2 == 0:
    print a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]

 elif len(a) % 2 == 1 and len(b) % 2 == 0:
    print a[:(len(a)/2)+1] + b[:(len(b)/2)] + a[(len(a)/2)+1:] + b[(len(b)/2):] 

 elif len(a) % 2 == 0 and len(b) % 2 == 1:
     print a[:(len(a)/2)] + b[:(len(b)/2)+1] + a[(len(a)/2):] + b[(len(b)/2)+1:] 

 else :
     print a[:(len(a)/2)+1] + b[:(len(b)/2)+1] + a[(len(a)/2)+1:] + b[(len(b)/2)+1:]

-3

Одного &(не подвійного &&) достатньо, або як підказує верхня відповідь, ви можете використовувати "і". Я також виявив це в пандах

cities['Is wide and has saint name'] = (cities['Population'] > 1000000) 
& cities['City name'].apply(lambda name: name.startswith('San'))

якщо ми замінимо "&" на "і", воно не працюватиме.


1
Одномісний & не буде короткого замикання виразу (тобто обидва вони будуть оцінені незалежно від зворотного значення першого виразу)
user528025

-4

можливо, з & натомість% швидше і легше читати

інші тести парні / непарні

х рівний? x% 2 == 0

х непарне? не х% 2 == 0

можливо, більш чіткий з порозрядним і 1

х непарне? х & 1

х рівний? не х і 1 (не непарно)

def front_back(a, b):
    # +++your code here+++
    if not len(a) & 1 and not len(b) & 1:
        return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
    else:
        #todo! Not yet done. :P
    return

-4

Використання "і" в умовних умовах. Я часто використовую це під час імпорту в Jupyter Notebook:

def find_local_py_scripts():
    import os # does not cost if already imported
    for entry in os.scandir('.'):
        # find files ending with .py
        if entry.is_file() and entry.name.endswith(".py") :
            print("- ", entry.name)
find_local_py_scripts()

-  googlenet_custom_layers.py
-  GoogLeNet_Inception_v1.py

14
На це питання було задано і відповіли майже 7 років тому. Що ваша відповідь додає до тих відповідей, які вже є тут? Загалом, якщо у вас є щось напрочуд нове сказати, не слід додавати нову відповідь на старе питання - де старі вимірюються як кілька років - коли вже є хороші відповіді.
Джонатан Леффлер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.