在if语句中,Python等效于&&(逻辑与)


827

这是我的代码:

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
显然,塞尔吉奥想知道为什么他的代码被破坏了,但是我对问题的标题读得更多。为什么&&仍然无法使用?==和!=可用(但我知道是和不是)。为什么不包括此语法?个人喜好?
PhysicalMichael

5
@ vgm64:为什么要包括不能改善单个方面的冗余语法?
康拉德·鲁道夫

27
在我看来,解释器应该(而不是打印出一个晦涩的“ SyntaxError:无效语法”)-检测用户是否已使用&&并向他们建议他们可能想使用该关键字and。类似的事情++以及来自其他语言的其他常见运算符也是如此。
ArtOfWarfare 2013年

3
@physicsmichael“应该有一种,最好只有一种明显的方式。” import this
尼克T

3
@KonradRudolph它绝对改善了语言的各个方面。对于曾经使用任何其他语言的人来说,它更加一致和直观。这个问题的存在和流量之大,这一事实清楚地凸显了这个问题是人们共同的症结所在。
jterm

Answers:


1468

您可能想要and而不是&&


2
我应该为此做些什么:如果x =='n'和y =='a'或y =='b':<要做某事>它会起作用吗?@ChristopheD
衍射

7
@diffracteD:如果要覆盖标准的运算符优先级,请使用括号(您可以在此处了解:ibiblio.org/g2swap/byteofpython/read/operator-precedence.html
ChristopheD

3
我喜欢大卫Titarenco给了一个切正贴例子
阿里克斯罗氏公司

7
键入两个字母后到达了这里&&AND并出现错误(不希望python想要小写单词and)。
Xeoncross

2
我认为您应该使用并查看:stackoverflow.com/questions/36921951/…–
user1761806

229

Python使用andor条件。

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

5
别忘了python也没有(很好!)
inspectorG4dget 2010年

9
您的示例的评估结果是“(如果有这个和这个)或那个”还是“如果有这个(这个或那个)”?
杰夫

12
@Jeff你的第一种方法。and 的优先级高于or
Buge 2014年

1
@Buge在您所链接的表中看起来像是“或”更高
Matt

5
@Matt表从最低优先级到最高优先级。如果您学习过布尔代数,就更容易记住优先级。“或”是加法,“和”是乘法。
Michael Stroud

48

我在IF条件中遇到错误。我究竟做错了什么?

得到a的原因SyntaxError&&Python中没有运算符。同样||!并且不是有效的 Python运算符。

您可能从其他语言中了解到的某些运算符在Python中使用不同的名称。逻辑运算符&&||实际上被称为andor。同样,逻辑否定运算符!称为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。二进制算术运算

逻辑运算符(像许多其他语言一样)具有使它们短路的优点。这意味着,如果第一个操作数已经定义了结果,则根本不会对第二个运算符求值。

为了说明这一点,我使用了一个简单地使用值的函数,将其打印并再次返回。方便查看由于print语句而实际评估的内容:

>>> 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           |
+-----------------+-------------------------+

TrueFalse代表什么bool(left-hand-side)回报,他们不必是TrueFalse,他们只需要返回TrueFalsebool被要求他们(1)。

因此,在Pseudo-Code(!)中,andand 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调用可用于自定义您的类的行为有andornot

为了说明如何进行自定义,我使用该类来再次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

两条评论:

  • 在Python中使用andor进行逻辑操作。
  • 使用4个空格而不是2缩进。您稍后将感谢自己,因为您的代码看起来与其他人的代码几乎相同。有关更多详细信息,请参见PEP 8

10

您可以使用andor执行类似C,C ++的逻辑操作。就像字面上的andis &&oris一样||


看看这个有趣的例子,

假设您要使用Python构建Logic Gate:

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

一个&(而不是double &&)就足够了,或者作为最高答案建议您可以使用'and'。我也在大熊猫中发现了

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

如果我们将“&”替换为“ and”,则将无法使用。


1
且不会短路表达式(意味着无论第一个表达式的返回值如何,都将对它们进行求值)
user528025

-4

也许用&代替%可以更快并保持可读性

其他测试奇数/奇数

x是偶数?x%2 == 0

x是奇数?不是x%2 == 0

也许按位和1更清楚

x是奇数?x&1

x是偶数?不是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

-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年前,有人问过这个问题。您的答案对已经存在的答案又有什么帮助?通常,除非您有令人惊讶的新内容要说,否则,在已有好答案的情况下,您不应为旧问题(新问题以多年为单位)添加新答案。
乔纳森·莱夫勒
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.