我遇到了一些关于python增强赋值+=的有趣事情。
如果a是一种“更简单”的数据类型,那么似乎并不总是为a += b完成自动数据类型转换,而a = a + b似乎总是有效
完成转换的情况
a = 1
b = 1j
a = 1
b = 0.5未完成转换的情况
from numpy import array
a = array([0, 0 ,0])
b = array([0, 0, 1j])在a += b之后,a仍然是整数矩阵,而不是复数矩阵
我曾经认为a += b和a = a + b是一样的,他们在底层实现上有什么不同?
发布于 2010-12-08 07:04:19
对于+操作符,Python定义了对象可以实现的三个“特殊”方法:
__add__:添加两个项目(+运算符)。执行a + b时,a的__add__方法将作为argument.__radd__:反射的add通过b调用;对于a + b,b的__radd__方法将通过a作为实例调用。只有当a不知道如何做加法,并且两个对象是不同的原地添加时才使用;用于a += b,其中结果被赋值回types.__iadd__:变量。这是单独提供的,因为可以以更有效的方式实现它。例如,如果a是一个列表,则a += b与a.extend(b)相同。然而,在c = a + b的情况下,您必须在扩展它之前创建a的副本,因为在这种情况下a不会被修改。请注意,如果您不实现__iadd__,那么Python将只调用__add__。因此,由于这些不同的操作是用不同的方法实现的,所以实现它们是可能的(但通常是不好的做法),因此它们做的事情完全不同,或者在这种情况下,可能只是稍微不同的事情。
其他人已经推断出您正在使用NumPy并解释了它的行为。但是,您询问了底层实现。希望您现在能明白为什么有时a += b与a = a + b不是一回事。顺便说一句,对于其他操作,也可以实现类似的三个方法。有关所有受支持的就地方法的列表,请参阅this page。
发布于 2010-12-08 06:57:47
如果array为numpy.array (您实际上没有指定),那么发生的问题是因为这些数组不能更改其类型。在没有类型说明符的情况下创建数组时,它会猜测类型。如果您随后尝试执行类型不支持的操作(如将其添加到具有较大域的类型中,如complex),numpy知道执行计算,但它也知道结果只能存储在具有较大域的类型中。它会抱怨(至少在我的机器上,是我第一次做这样的赋值),结果不符合。当您执行常规加法时,在任何情况下都必须创建一个新的数组,numpy为它提供了正确的类型。
>>> a=numpy.array([1])
>>> a.dtype
dtype('int32')
>>> b=numpy.array([1+1j])
>>> b.dtype
dtype('complex128')
>>> a+b
array([ 2.+1.j])
>>> (a+b).dtype
dtype('complex128')
>>> a+=b
>>> a
array([2])
>>> a.dtype
dtype('int32')
>>> 发布于 2010-12-08 06:53:29
a = a + b和a += b之间的区别在于,后一种添加将在任何可能的情况下“就地”完成,这意味着通过更改对象a。你可以通过列表很容易地看到这一点。
a = b = [1, 2]
a += [3]
print b # [1, 2, 3]
a = b = [1, 2]
a = a + [3]
print b # [1, 2]https://stackoverflow.com/questions/4382246
复制相似问题