list的一个问题是,如果使用range生成一个较大的list,而在使用的时候只使用1个或前几个,就会造成大量的浪费。(python2)
是一种可以对其进行迭代的程序(通常是for循环),但是它的值只需要延迟产生(lazily).
method one: def lazy_range(n): i = 0 while i < n: yield i i += 1 for i in lazy_range(10): print(i)# dosomethingwith(i)在python3中range本身就是lazily的。 ⚠️延迟的缺点是,你只能通过生成器迭代一次,如果需要多次迭代某个对象,你就需要每次都重新创建一个生成器,或者使用list。
method two: 使用包含在圆括号中的for语句解析: lazy_evens_below_20 = (i for i in range(20) if i%2== 0) print(lazy_evens_below_20)有时候,想在一个list上进行迭代,并且同时使用它的元素和索引 在一个已知的list上面进行迭代
for i,document in enumerate(documents): do_something(i,document) # i:index,document:element for i,_ in enumerate(documents): do_something(i,documents) # only index如果想要把两个或者多个list压缩在一起,可以使用zip同时把多个list转换为一个对应元素的tuple 的single list:
list1 = [1,2,3] list2 = ['a','b'] list=zip(list1,list2) print(tuple(list)) list1 = [1,2,3] list2 = ['a','b'] list3 = [4,5,6] list=zip(list1,list2,list3) print(tuple(list))if the length of these lists aren’t same, zip will end at the shortest list (最短截止)
*(星号)执行参数拆分argument unpacking ⚠️可以在任何函数上进行参数拆分
def add(a,b): return a+b ans = add(1,2) print(ans) ans = add(*[1,2]) print(ans)如果想要创建一个更高阶的函数,把某个函数f作为input,并返回一个对任意输入都返回f值两倍的函数:
def doubler(f): def g(x): return 2*f(x) return g def f2(x,y): return x+y g = doubler(f2(1,2)) print(g(1,2))对于有多个参数的函数就不适用 需要一个可以取任意参数的函数的method,利用参数拆分可以做到:
def magic(*args,**kwargs): print("unnamed args:",args) print("keyword args:",kwargs) magic(1,2,key='word',key2='word2')输出的未命名的args和关键字kwargs如下: 也就是说当定义了这样一个function时,args是它的一个未命名参数的tuple,kwargs是它的一个已命名参数的dict 反过来也适用,可以使用一个list/tuple和dict来给函数提供参数
def other_way_magic(x,y,z): return x+y+z x_y_list = [1,2] z_dict = {"z":3} print(other_way_magic(*x_y_list,**z_dict))用它可以将任意参数作为输入的高阶函数
def doubler_correct(f): def g(*args,**kwargs): return 2*f(*args,**kwargs) return g def f2(x,y): return x+y g = doubler_correct(f2) print(g(1,2))因为传入函数的参数具有不确定性,所以像最开始那样直接固定参数个数不行,所以才用这种参数随便的method。