Эквивалент Python & & (logical-and) в if-операторе

вот мой код:

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 ответов


вы хотите and вместо &&.


Python использует and и or условные.

то есть

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

два комментария:

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

Я пошел с purlely математическое решение:

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:]

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

есть причина, по которой вы получаете SyntaxError нет && оператор в Python. Аналогичным образом || и ! are не действительным операторы 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).

так в псевдо-код(!) the 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 или фреймы данных), то неявное 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])

если вы имеете дело только с boolean массивы вы также можете использовать двоичные операторы с 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 на результат. Так что эти тонкости могут быть не актуальны для вы.


вы используете and и or для выполнения логических операций, как в C, с++. Как буквально and is && и or is ||.


взгляните на этот забавный пример,

скажем, вы хотите построить логические ворота в 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

надеюсь, что это помогает!


наверное, это не лучший код для этой задачи, но работает -

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:]

использование "и" в условных. Я часто использую это при импорте в 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

один & (не &&) достаточно или, как подсказывает верхний ответ, вы можете использовать "и". Я также нашел это в панд

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

если мы заменим " & "на" И", это не будет работать.


возможно, с & вместо % быстрее и удобочитаемость

другие тесты, четное/нечетное

х даже ? x % 2 == 0

x нечетно ? не x % 2 == 0

может быть, более ясно с побитовым и 1

x нечетно ? x & 1

х даже ? не x & 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