Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ';和';(布尔)vs'&';(按位)-为什么列表与numpy数组的行为有所不同?_Python_Numpy_Bit Manipulation_Boolean Expression_Ampersand - Fatal编程技术网

Python ';和';(布尔)vs'&';(按位)-为什么列表与numpy数组的行为有所不同?

Python ';和';(布尔)vs'&';(按位)-为什么列表与numpy数组的行为有所不同?,python,numpy,bit-manipulation,boolean-expression,ampersand,Python,Numpy,Bit Manipulation,Boolean Expression,Ampersand,是什么解释了列表和NumPy数组上布尔运算和按位运算的行为差异? 我对Python中&与和的正确使用感到困惑,如以下示例所示 mylist1 = [True, True, True, False, True] mylist2 = [False, True, False, True, False] >>> len(mylist1) == len(mylist2) True # ---- Example 1 ---- >>> mylist1 and m

是什么解释了列表和NumPy数组上布尔运算和按位运算的行为差异?

我对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 would have expected [False, True, False, False, False]

# ---- Example 2 ----
>>> mylist1 & mylist2
TypeError: unsupported operand type(s) for &: 'list' and 'list'
# Why not just like example 1?

>>> import numpy as np

# ---- Example 3 ----
>>> 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()
# 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个例子

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 would have expected [False, True, False, False, False]

# ---- Example 2 ----
>>> mylist1 & mylist2
TypeError: unsupported operand type(s) for &: 'list' and 'list'
# Why not just like example 1?

>>> import numpy as np

# ---- Example 3 ----
>>> 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()
# 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引导我获得了所需的输出,因此这很好,但我仍然不清楚何时/如何/为什么应该使用
&
。为什么列表和NumPy数组在使用这些运算符时表现不同

有人能帮我理解布尔运算和按位运算之间的区别,解释为什么它们处理列表和NumPy数组的方式不同吗?

  • 在Python中,
    X和Y
    的表达式返回
    Y
    ,假设
    bool(X)=True
    X
    Y
    中的任何一个计算为False,例如:

    True and 20 
    >>> 20
    
    False and 20
    >>> False
    
    20 and []
    >>> []
    
  • 只是没有为列表定义按位运算符。但它是为整数定义的——在数字的二进制表示上进行运算。考虑16(01000)和31(11111):

  • NumPy不是通灵者,它不知道你是不是这个意思 e、 g.
    [False,False]
    在逻辑表达式中应等于
    True
    。在这种情况下,它覆盖了标准的Python行为,即:“任何
    len(collection)==0的空集合都是
    False

  • 可能是NumPy阵列的&operator的预期行为


  • 测试这两个表达式在逻辑上是否都是
    True
    ,而
    (与
    True
    /
    False
    值一起使用时)测试这两个表达式是否都是
    True

    在Python中,空的内置对象通常在逻辑上被视为
    False
    ,而非空的内置对象在逻辑上被视为
    True
    。这有助于实现一个常见用例,即如果列表为空,则需要执行某些操作,如果列表为空,则需要执行其他操作。注意,这意味着列表[False]在逻辑上是
    True

    >>> if [False]:
    ...    print 'True'
    ...
    True
    
    因此,在示例1中,第一个列表是非空的,因此逻辑上
    True
    ,因此
    的真值与第二个列表的真值相同。(在我们的例子中,第二个列表是非空的,因此在逻辑上是
    True
    ,但是识别它需要一个不必要的计算步骤。)

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

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

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

    示例4只是一个矢量化位
    操作

    底线

    • 如果不处理数组,也不执行整数的数学运算,则可能需要

    • 如果有要组合的真值向量,请将
      numpy
      &
      一起使用


      • 短路布尔运算符(
        )不能被重写,因为如果不引入新的语言功能或牺牲短路,就没有令人满意的方法来实现这一点。您可能知道,也可能不知道,它们计算第一个操作数的真值,并根据该值计算并返回第二个参数,或者不计算第二个参数并返回第一个参数:

        something_true and x -> x
        something_false and x -> something_false
        something_true or x -> something_true
        something_false or x -> x
        
        请注意,返回的是实际操作数(计算结果),而不是其真值

        自定义其行为的唯一方法是重写
        \uuuuu nonzero\uuuuu
        (在Python3中重命名为
        \uuuuuuu bool\uuuuuu
        ),这样可以影响返回的操作数,但不能返回其他操作数。列表(和其他集合)在包含任何内容时定义为“真实”,在为空时定义为“虚假”

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


        &
        |
        (顺便说一句,
        不是
        )可以完全覆盖,因为它们不会短路。当被重写时,它们可以返回任何内容,而NumPy很好地利用了这一点来执行元素级操作,就像它们对几乎任何其他标量操作所做的那样。另一方面,列表不跨元素广播操作。正如
        mylist1-mylist2
        没有任何意义,
        mylist1+mylist2
        意味着完全不同的东西一样,列表没有
        &
        操作符。

        使用Python列表的操作在列表上操作
        list1和list2
        将检查
        list1
        是否为空,如果为空则返回
        list1
        ,如果为空则返回
        list2
        list1+list2
        list2
        附加到
        list1
        ,因此您将获得一个包含
        len(list1)+len(list2)
        元素的新列表

        仅在应用元素级时才有意义的运算符(如
        &
        )会引发
        类型错误
        ,因为如果不循环元素,则不支持元素级操作

        Numpy阵列支持按元素操作
        if bool(array1):
            return array2
        else:
            return array1
        
        >>> 3 & 1
        1
        
        >>> 0b0011 & 0b0001
        0b0001
        
        In [74]: mylist1 = [False]
        In [75]: mylist2 = [False, True, False,  True, False]
        In [76]: mylist1 and mylist2
        Out[76]: [False, True, False, True, False]
        In [77]: mylist2 and mylist1
        Out[77]: [False]
        
        array([[ 1,  2,  3,  4,  5],
               [ 6,  7,  8,  9, 10],
               [11, 12, 13, 14, 15],
               [16, 17, 18, 19, 20],
               [21, 22, 23, 24, 25]])
        
        np.sum(mat)  ## --> gives 325
        sum(mat)     ## --> gives array([55, 60, 65, 70, 75])