和
a = 5 a += 5 print(a)这两段代码都是输出10,我一直以为类似上边的+=和=是一样的,不过下面的2段代码:
def f(x): x += [10, 11, 12, 13, 14, 15] return x a = [1, 2, 3, 4, 5] b = f(a) print(b) # [1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15] print(a) # [1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15] def f(x): x = x + [10, 11, 12, 13, 14, 15] return x a = [1, 2, 3, 4, 5] b = f(a) print(b) # [1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15] print(a) # [1, 2, 3, 4, 5]可以看到对于+=和=似乎不同。再来看两段代码
def f(x): x += (4, 5, 6) return x a = (1, 2, 3) b = f(a) print(a) # (1, 2, 3)def f(x): x = x + (4, 5, 6) return x a = (1, 2, 3) b = f(a) print(a) # (1, 2, 3)
如果a是一个tuple 那么看起来+=和=的效果一样
下面是我的个人理解:
类似上边的+= 和 =是不一样的,当不可变类型传入时如tuple,+=和=的效果一样,而可变类型传入,如list时,+=和=效果不一样。可以确定的是在函数里类似x = x+ ...,这里左边的x是一个局部变量,这个x的改变不会影响外边的a。 在python中,什么都可以看作对象,那么这些符号,可以看做指针,有些类型不可变,那么是说这个指针指向的内容不能改变。当函数里使用+=时,对于可变类型,还是用的原来那个地址,所以再次输出a时,a会改变。而对于不可变类型,指针指向的内容不可变,x+=... 这里的x是一个新的地址了,所以再次输出a时,a不会改变。
查看list源码 如下:
def __iadd__(self, *args, **kwargs): # real signature unknown """ Implement self+=value. """ pass可以看到+=对于list来说,自身改变了。而tuple中没有此函数。
应用:
假设x是一个ndarray
假设外部调用a = f(x)
那么x本身的期望变为0.5,标准差变为0.25
同时在函数里 x = np.clip(x, 0, 1)在此之后x所做的改变不会影响外边的实参x
通过a = f(x)后 x的期望为0.5,标准差为0.25
而a的期望为127.5 标准差为63.75 且值位于0到255之间
代码来自https://github.com/keras-team/keras/blob/master/examples/conv_filter_visualization.py
def deprocess_image(x): """utility function to convert a float array into a valid uint8 image. # Arguments x: A numpy-array representing the generated image. # Returns A processed numpy-array, which could be used in e.g. imshow. """ # normalize tensor: center on 0., ensure std is 0.25 x -= x.mean() x /= (x.std() + K.epsilon()) x *= 0.25 # clip to [0, 1] x += 0.5 x = np.clip(x, 0, 1) # convert to RGB array x *= 255 if K.image_data_format() == 'channels_first': x = x.transpose((1, 2, 0)) x = np.clip(x, 0, 255).astype('uint8') return x