拆箱
使用 .(dot) 来访问字典成员
numpy 一维数组与二维数组相加
class 中的 self
global & nonlocal
默认参数陷阱
交换变量
行内 if 语句
带索引的列表迭代
… 持续更新中
拆箱
1 2 3 4 5 6 7 >>> a, *b, c = [1 , 2 , 3 , 4 , 5 ]>>> a1 >>> b[2 , 3 , 4 ] >>> c5
使用 .(dot) 来访问字典成员
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 class Map (dict) : def __init__ (self, *args, **kwargs) : super(Map, self).__init__(*args, **kwargs) for arg in args: if isinstance(arg, dict): for k, v in arg.items(): self[k] = v if kwargs: for k, v in kwargs.items(): self[k] = v def __getattr__ (self, attr) : return self.get(attr) def __setattr__ (self, key, value) : self.__setitem__(key, value) def __setitem__ (self, key, value) : super(Map, self).__setitem__(key, value) self.__dict__.update({key: value}) def __delattr__ (self, item) : self.__delitem__(item) def __delitem__ (self, key) : super(Map, self).__delitem__(key) del self.__dict__[key] m = Map({'first_name' : 'Eduardo' }, last_name='Pool' , age=24 , sports=['Soccer' ]) m.new_key = 'Hello world!' m['new_key' ] = 'Hello world!' print(m.new_key) print(m['new_key' ]) m.new_key = 'Yay!' m['new_key' ] = 'Yay!' del m.new_keydel m['new_key' ]
或者使用一个简化版的:
1 2 3 4 5 6 7 8 9 10 11 class dict2 (dict) : def __init__ (self, **kwargs) : dict.__init__(self, kwargs) self.__dict__ = self config = dict2(**{ "timesteps_per_batch" : 1000 , "max_pathlength" : 10000 , "max_kl" : 0.01 , "cg_damping" : 0.1 , "gamma" : 0.95 })
numpy 一维数组与二维数组相加
在写 tensorflow 时,dense
层的输出是一个二维数组,假设为 \(n \times 1\) 的 Tensor
,而此时与另一个一维 Tensor
相加,则会出现意想不到的问题。用 numpy 的矩阵举个例子:
1 2 3 4 5 6 7 8 >>> import numpy as np>>> >>> a = np.array([1 , 2 , 3 ])>>> b = np.array([[1 ], [2 ], [3 ]])>>> print(a + b)[[2 3 4 ] [3 4 5 ] [4 5 6 ]]
结果是个 \(3 \times 3\) 的矩阵,难怪程序不收敛。所以在实际写程序的过程中,尽量设置相同 Tensor
的维数。
class 中的 self
类中所有函数无论有没有参数,在定义成员函数时必须接受一个 self
参数:
1 2 3 4 5 6 class foo (object) : def bar (self) : pass def lee (self, *args, **kwargs) : pass
global & nonlocal
global
当在局部作用域中要使用全局变量时,要使用 global
来修饰全局变量,如果不需要修改全局变量,也可以不使用 global
关键字。
1 2 3 4 5 6 7 8 9 10 11 g = 0 def foo () : g = 10 print('local' , g) print('global' , g) foo() print('global' , g)
输出:
1 2 3 global 0 local 10 global 0
这时第5行的 g
为局部变量,尽管与全局变量 g
的名字相同,但是两个不同的变量。如果要修改全局变量,则要加上 global
:
1 2 3 4 def foo () : global g g = 10 print('local' , g)
输出:
1 2 3 global 0 local 10 global 10
nonlocal
nonlocal
与 global
类似,nonlocal
用来修饰外层(非全局)变量。
1 2 3 4 5 6 7 8 9 10 11 12 def foo () : g = 0 def bar () : g = 10 print('bar' , g) bar() print('foo' , g) foo()
输出:
如果要修改外部变量 g
则要加上 nonlocal
关键字:
1 2 3 4 def bar () : nonlocal g g = 10 print('bar' , g)
输出:
默认参数陷阱
1 2 3 4 5 6 7 def foo (arr=[], el=None) : arr.append(el) print(arr) foo(el=1 ) foo(el=2 )
对于这样一个函数,其中有默认参数 arr=[]
,如果是 javascript 或其他编程语言的话,每次调用函数都是默认把一个空 list
赋值给 arr
,但 python 不是这么做的,它的输出为:
因为 python 函数的参数默认值,是在编译阶段就确定的,之后所有的函数调用,如果参数不显示的赋值,默认参数都是指向在编译时就确定的对象指针。
对于普通的不可变变量 int
, string
, float
, tuple
,在函数体内如果修改了该参数,那么参数就会重新指向另一个新的不可变值。
但对于可变对象 list
, dict
,所有对默认参数的修改实际上都是对编译时已经确定的那个对象的修改。
交换变量
1 2 3 4 5 6 >>> x = 1 >>> y = 2 >>> >>> x, y = y, x>>> print(x, y)2 1
行内 if 语句
1 2 3 4 >>> print("Hello" if True else "World" )Hello >>> print("Hello" ) if False else print("World" )World
带索引的列表迭代
1 2 3 4 5 6 7 >>> arr = ['foo' , 'bar' , 'lee' ]>>> for index, el in enumerate(arr):... print(index, el)... 0 foo1 bar2 lee