为了账号安全,请及时绑定邮箱和手机立即绑定

python中‘和’(布尔)与‘&’(按位)之间的区别。为什么与列表和numpy数组的行为不同?

python中‘和’(布尔)与‘&’(按位)之间的区别。为什么与列表和numpy数组的行为不同?

莫回无 2019-10-16 12:09:52
python中‘和’(布尔)与‘&’(按位)之间的区别。为什么与列表和numpy数组的行为不同?什么解释了列表和numpy.Array上的布尔操作和按位操作的行为差异?我对如何正确使用&“VS”and在python中,下面的简单示例说明了这一点。    mylist1 = [True,  True,  True,  False,  True]     mylist2 = [False, True, False,  True, False]       >>> len(mylist1) == len(mylist2)     True     # ---- Example 1 ----     >>>mylist1 and mylist2      [False, True, False, True, False]     #I am confused: I would have expected [False, True, False, False, False]     # ---- Example 2 ----     >>>mylist1 & mylist2      *** TypeError: unsupported operand type(s) for &: 'list' and 'list'     #I am confused: Why not just like example 1?      # ---- Example 3 ----     >>>import numpy as np    >>> np.array(mylist1) and np.array(mylist2)      *** ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()     #I am confused: Why not just like Example 4?       # ---- Example 4 ----     >>> np.array(mylist1) & np.array(mylist2)      array([False,  True, False, False, False], dtype=bool)     #This is the output I was expecting!这,这个回答,还有这个回答两者都让我明白“和”是布尔运算,但是'&'是按位操作。我曾经是读一些信息,以更好地理解按位运算,但是我很难用这些信息来理解我上面的4个例子。注意,在我的特定情况下,我想要的输出是一个新列表,其中:    len(newlist) == len(mylist1)      newlist[i] == (mylist1[i] and mylist2[i]) #for every element of newlist上面的示例4引导我找到了我想要的输出,所以这很好。但是,我对何时/如何/为什么要使用‘和’VS‘&’感到困惑。为什么列表和numpy数组与这些运算符的行为不同?有谁能帮助我理解布尔操作和按位操作之间的区别,来解释为什么它们处理列表和numpy.数组的方式不同呢?我只想确保继续正确地使用这些操作。非常感谢你的帮助!Numpy version 1.7.1python 2.7References all inline with text.
查看完整描述

3 回答

?
FFIVE

TA贡献1797条经验 获得超6个赞

and测试这两个表达式是否符合逻辑。True&(当与True/False)测试,如果两者都是True.

在Python中,空内置对象通常被视为逻辑上的对象。False而非空内置在逻辑上是True..这简化了通用例,如果列表为空,则需要执行某些操作;如果列表不为空,则需要执行其他操作。请注意,这意味着列表[false]在逻辑上是True:

>>> if [False]:...    print 'True'...True

因此,在示例1中,第一个列表是非空的,因此逻辑上是这样的。True的真值and与第二个列表相同。(在我们的例子中,第二个列表是非空的,因此逻辑上是这样的。True,但要确定这一点,就需要进行不必要的计算。)

例如,列表不能以按位的方式进行有意义的组合,因为它们可以包含与元素不同的任意内容。可以按位组合的东西包括:真、假、整数。

相反,NumPy对象支持矢量化计算。也就是说,它们允许您对多个数据执行相同的操作。

示例3失败是因为NumPy数组(长度>1)没有真值,因为这样可以防止基于向量的逻辑混淆。

示例4只是一个矢量化位。and行动。

底线

  • 如果您没有处理数组,也没有执行整数的数学操作,那么您可能需要and.

  • 如果您有要组合的真值向量,请使用numpy带着&.



查看完整回答
反对 回复 2019-10-17
?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

短路布尔运算符(andor)不能过度使用,因为在不引入新的语言特性或牺牲短路的情况下,没有令人满意的方法可以做到这一点。您可能知道,也可能不知道,它们计算第一个操作数的真值,并根据该值计算并返回第二个参数,或者不计算第二个参数并返回第一个参数:

something_true and x -> x
something_false and x -> something_false
something_true or x -> something_true
something_false or x -> x

请注意,返回的是实际操作数,而不是其真值。

定制它们行为的唯一方法是重写__nonzero__(重命名为__bool__在Python 3中,您可以影响返回哪个操作数,但不会返回不同的操作数。当列表(和其他集合)包含任何内容时,它们被定义为“真实的”,而当它们是空的时,定义为“Falsey”。

NumPy数组拒绝这个概念:对于它们所针对的用例,两种不同的真理概念是常见的:(1)是否有任何元素为真,(2)是否所有元素都为真。由于这两者完全(和默默地)不兼容,而且两者都不明显更正确或更常见,所以NumPy拒绝猜测,并要求您显式使用.any().all().

&|(和not,顺便说一句)能,会,可以完全超越,因为他们不会短路。当超限时,它们可以返回任何内容,NumPy很好地利用了它来执行元素级操作,就像对其他任何标量操作一样。另一方面,列表不会跨元素广播操作。就像mylist1 - mylist2并不意味着什么mylist1 + mylist2意味着完全不同的东西,没有&列表的运算符。



查看完整回答
反对 回复 2019-10-17
?
杨__羊羊

TA贡献1943条经验 获得超7个赞

关于list

首先,这是非常重要的一点,一切都会随之发生(我希望)。

在普通的Python里,list在任何方面都没有什么特别之处(除了构造时有可爱的语法,这主要是历史上的意外)。一次[3,2,6],就所有意图和目的而言,它只是一个普通的Python对象,就像一个数字。3,集{3,7},或者一个函数lambda x: x+5.

(是的,它支持更改元素,支持迭代和许多其他东西,但这正是类型:它支持一些操作,而不支持其他一些操作。int支持提升到一个能力,但这并不意味着它很特别-它就是int。Lambda支持调用,但这并不意味着它很特别-毕竟,lambda就是这样做的:)。

关于and

and不是运算符(您可以称它为“运算符”,但也可以调用“for”操作符:)。Python中的运算符是通过调用某些类型的对象的方法实现的,通常是作为该类型的一部分编写的。一个方法无法对其一些操作数进行评估,但是and能够(而且必须)做到这一点。

结果就是and不能超载,就像for不能超载。它是完全通用的,并通过指定的协议进行通信。你能,会,可以是自定义协议的一部分,但这并不意味着您可以更改and完全地。议定书是:

想象一下Python对“a和b”的解释(这并不是这样的,但它有助于理解)。当提到“and”时,它会查看它刚刚计算过的对象(A),并问它:“您是真的吗?”*你是True?)如果您是一个类的作者,您可以自定义这个答案。如果a回答“不”,and(完全跳过b,根本不对其进行评估,)说:a是我的成绩(:错误是我的结果)。

如果a不回答,and问它:你的长度是多少?(同样,您可以将其自定义为a),如果a答案0,and是否与上述相同-认为它是假的(),跳过b,并给出a结果。

如果a回答第二个问题(“你的长度是多少”),或者它根本没有回答,或者对第一个问题回答“是”(“你是真的”),and评估b,并说:b是我的结果。注意它确实有b任何问题。

换句话说,所有这些都是a and b几乎和b if a else a,除非a只计算一次。

现在用笔和纸坐几分钟,让自己相信,当{a,b}是{True,false}的子集时,它的工作原理与布尔运算符完全一样。但我希望我已经说服你,它是更一般,正如你会看到,更有用的方式。

把这两者结合起来

现在我希望你理解你的例子1。and不管mylist 1是一个数字、列表、lambda还是一个类argmhbl的对象。它只关心mylist 1对协议问题的回答。当然,mylist 1回答了关于长度的问题,所以返回mylist 2。仅此而已。这与mylist 1和mylist 2的元素无关-它们不会在任何地方输入图片。

第二个例子:&在……上面list

另一方面,&操作员和其他人一样,就像+例如。可以通过在该类上定义特殊方法来定义类型。int将其定义为按位“和”,bool将其定义为逻辑“和”,但这只是一个选项:例如,set和一些其他对象(如dict键视图)将其定义为集交集。list只是没有定义它,可能是因为Guido没有想到任何明显的方法来定义它。

蒙皮

在另一条腿上:-D,numpy数组特别,或者至少他们想成为。当然,numpy.Array只是一个类,它不能覆盖and无论如何,它也做了次好的事情:当被问到“你是真的”时,numpy.Array会引发一个ValueError,有效地说“请重新表述这个问题,我对真相的看法不适合你的模型”。(请注意,ValueError消息没有提到and-因为numpy.Array不知道就是问它这个问题,它只是在说真理。)

&完全不同的故事。数组可以根据自己的意愿定义它,并定义&与其他运营商保持一致:点态。所以你终于得到了你想要的。

HTH,



查看完整回答
反对 回复 2019-10-17
  • 3 回答
  • 0 关注
  • 338 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信