如果我这样做
a = [1, 2, 7]
a - a[-1]
我得到TypeError: unsupported operand type(s) for -: 'list' and 'int'
但是,我有一个由b
组成的列表np.float64
,以下代码有效:
type(b)
# list
b - b[-1]
# array([ 281.04209146, 6.57013103, 0. ])
我认为这是因为b
中的数字是np.float64
,而b
有点强制转换为np.array
,然后广播就会发生。
但我仍然觉得这种行为令人惊讶:因为列表中的所有元素都不需要具有相同的类型,如果b[0]
是一个字符串怎么办? b - b[-1]
中的操作数仍然是list
和np.float64
,那么b - b[-1]
为什么不提出TypeError
?
编辑:有人回答说list
和np.array
不同;好吧,我知道。但是b
不是np.array
。 行为就像一个,但它的类型是list
,就像我在代码段中所述。
以下是b
的最小工作示例:
b
# [1598.717274996219, 1324.245314569733, 1317.6751835362861]
type(b[0])
# numpy.float64
答案 0 :(得分:2)
在A-B
这样的表达式中,解释器可以将其实现为A.__sub__(B)
或B.__rsub__(A)
。
列出了mul
和add
,但没有sub
In [29]: [1,2,3]*3
Out[29]: [1, 2, 3, 1, 2, 3, 1, 2, 3]
In [30]: [1,2,3]+[1]
Out[30]: [1, 2, 3, 1]
In [31]: [1,2,3]-3
TypeError: unsupported operand type(s) for -: 'list' and 'int'
np.ndarray
实现了__rsub__
In [32]: [1,2,3]-np.array([1,2,3])
Out[32]: array([0, 0, 0])
# np.array([1,2,3]).__rsub__([1,2,3])
该方法试图将LHS转换为数组,因此该表达式与:
相同In [33]: np.asarray([1,2,3]) - np.array([1,2,3])
Out[33]: array([0, 0, 0])
如果列表包含字符串,则会失败:
In [35]: ['a',2,3]-np.array([1,2,3])
TypeError: ufunc 'subtract' did not contain a loop with signature matching types dtype('<U11') dtype('<U11') dtype('<U11')
因为该列表变成了一个字符串数组:
In [36]: np.asarray(['a',2,3])
Out[36]:
array(['a', '2', '3'],
dtype='<U1')
没有实现带字符串dtype的数组减法。
我使用数组RHS编写的所有内容都适用np.float64
。 np.float64(10)
行为(在大多数情况下)与np.array(10.0)
相同。
所有这些b
的减法都是相同的:
b = [np.float64(10), np.float64(1)]
b - b[-1]
b - np.float64(1)
b - np.array(1.0)
np.array(b) - np.array(1.0)
总而言之,如果RHS是某种数组,它也会将LHS列表转换为数组。从那里可以看出2个阵列是否兼容(形状和dtype)。
答案 1 :(得分:1)
但是当你TypeError
为字符串时,你不会得到相同的b[0]
。
b=[np.float_(a_) for a_ in a]
b
Out[4]: [1.0, 2.0, 7.0]
b-b[-1]
Out[5]: array([-6., -5., 0.])
b[0]='a'
b
Out[7]: ['a', 2.0, 7.0]
b-b[-1]
Traceback (most recent call last):
File "<#>", line 1, in <module>
b-b[-1]
TypeError: ufunc 'subtract' did not contain a loop with signature matching types dtype('<U32') dtype('<U32') dtype('<U32')
TypeError
中有不匹配类型的subtract
。在原文中,当np.float64
获得b[-1]
时,它会将整个表达式转换为numpy数组。因此,如果b[-1]
是一个字符串:
b[2]='a'
b-b[-1]
Traceback (most recent call last):
File "<#>", line 1, in <module>
b-b[-1]
TypeError: unsupported operand type(s) for -: 'list' and 'str'
您将回到原来的TypeError
。