Python-эквивалент && (логического-и) в операторе if


830

Вот мой код:

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

Я получаю ошибку в условном IF .
Что я делаю неправильно?


10
Ясно, что Серхио хотел знать, почему его код был взломан, но я немного подробнее прочитал заголовок вопроса. Почему && не будет доступно в любом случае? == и! = доступны (но отличаются от есть и нет, я знаю). Почему бы не включить этот синтаксис? Личное предпочтение?
физика Майкл

5
@ vgm64: Зачем включать избыточный синтаксис, который не улучшает ни одного аспекта?
Конрад Рудольф

27
Мне кажется, что интерпретатор должен вместо того, чтобы распечатывать загадочный «SyntaxError: неверный синтаксис», - обнаружить, что пользователь использовал, &&и предложить им, что они могли бы andвместо этого использовать ключевое слово . То же самое касается таких вещей, как ++и других распространенных операторов из других языков.
ArtOfWarfare,

3
@physicsmichael "должен быть один, и желательно только один, очевидный способ сделать это." import this
Ник Т

3
@KonradRudolph Это абсолютно улучшает аспекты языка. Он более последовательный и интуитивно понятный для всех, кто когда-либо использовал любой другой язык. тот факт, что этот вопрос существует и имеет столько же трафика, сколько он делает, ясно выдвигает на первый план эту проблему как общую точку преткновения для людей.
В

Ответы:


1474

Вы бы хотели 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получил ошибку (не ожидая, что python захочет ввести строчные буквы 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
Не забывайте , что питон также не имеет (ну и!)
inspectorG4dget

9
Ваш пример оценивает "(если это и это) или это" ИЛИ ", если это и (то или это)"?
Джефф

12
@Jeff Твой первый путь. and имеет более высокий приоритет, чем or.
Buge

1
@ Буге, похоже, «или» выше в таблице, которую вы связали
Мэтт

5
@Matt таблица идет от самого низкого приоритета к самому высокому. Легче запомнить приоритет, если вы изучали булеву алгебру; «или» - это сложение, а «и» - умножение.
Майкл Страуд

48

Я получаю ошибку в условном IF. Что я делаю неправильно?

Причина, по которой вы получаете, 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

Как вы можете видеть, выполняется только одно выражение print, поэтому 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 Series или 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

Надеюсь это поможет!



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.