a=5
a=a+5
print(a)
和
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