Python-эквивалент && (логического-и) в операторе 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

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

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

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

Я выбрал чисто математическое решение:

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

Ты используешь 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

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

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

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

В "операторе If" в Python вы должны использовать и, или, нет, и они эквивалентны &&, ||,! логические операторы, которые используются в других языках программирования

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

х странно? не х% 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
Другие вопросы по тегам