title: python语法拾遗
date: 2019-11-12 12:23:49
categories:
迭代通过for...in
来完成,作用对象可以是list,tuple,dict,str之类的可迭代对象。如下迭代dict类型:
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
print(key) #a,b,c
注:dict字典数据类型,内部原始没有顺序,故输出顺序可能不同。dict默认迭代key值,如要迭代value值,需要使用
for value in d.values()
;如要迭代键值对,要使用for k,v in d.items()
。
可迭代对象的判断方法,使用collections模块的Iterable类型判断:
from collections import Iterable
isinstance('abc',Iterable) # 返回True,即str为可迭代对象
enumerate
函数,可以将list变成索引-元素对:
for i,v in enumerate(['A', 'B', 'C']):
print(i,v)#0 A;1 B;2 C
创建方法(一):
将列表生成式的’[]‘改写成’()'即可,如:
L = [x for x in range(5)] #这是个列表
L2 = (x for x in range(5)) #这是个生成器
创建方法(二):
在循环函数内使用yield
关键字代替输出。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1
return 'done'
调用next()
函数可以逐个输出循环体内值,调用一次输出一次,直到输出完毕后,报StopIteration
错误。在循环体中,每执行一次yield则跳出该循环。
生成器也是可迭代对象,所以可以使用for...in
循环输出,且最后不会有StopIteration
报错。
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator,而可迭代对象叫:Iterable。所以,生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
iter()
函数将可迭代对象,转换为iterator。
map
函数:map(function_to_apply,list_of_inputs)
,接收两个参数,一个函数,一个Iterable
。该函数将序列的每个元素逐个作用到function上,并返回一个Iterator。
#e.g.
items = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, items)) # 1,4,9,16,25
除此之外,map
函数还可以接收,由函数组成的Iterable
:
def multiply(x):
return x*x
def add(x):
return x+x
funcs = [multiply,add]
for i in range(5):
print(list(map(lambda x: x(i),funcs)))
# Output:
# [0, 0]
# [1, 2]
# [4, 4]
# [9, 6]
# [16, 8]
reduce
函数:形式与map相同,但是参数函数必须接收两个值,reduce把结果继续和序列的下一个元素做累积计算,类似:reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
。
from functools import reduce
product = reduce((lambda x,y:x*y),[1,2,3,4])
# output:24
filter
函数:形式与map相同,但filter
将元素代入func做判断,返回满足条件的元素(Iterator)。
odd_list = list(filter((lambda x: x%2==1),[1,2,4,5,6,7]))
在函数中返回函数,则“外部函数”的变量可以被“内部函数”引用,但是,返回函数不要引用任何循环变量,或者后续会发生变化的变量。函数名后没有加"()“的,只能起到传递函数的作用,加上”()"才能真正执行。如下例
def adder(x):
def wrapper(y):
return x + y
return wrapper
adder5 = adder(5)
# 输出 15
adder5(10)
# 输出 11
adder5(6)
函数可以作为参数传给另⼀个函数。装饰器的作用就是将目标函数①作为参数,传递给另一个函数②。以达到在不改变目标函数①的前提下,添加函数②的功能,还可以接收函数②的新参数(可能需要多层嵌套)。类似如此:
@func1 #func1一般为针对func2的闭包函数。
def func2():
print('some')
#定义完毕后,执行func2时,实际是执行func2 = func1(func2)。此时func2指向的是func1的内部函数。可通过func2.__name__查看。
#此时,在最后的"封装"步骤前添加:@functools.wraps(func)可以修正__name__
示例:
from functools import wraps
def decorator_name(f):
@wraps(f)
def decorated(*args,**kwargs):
if not can_run:
return 'func will not run'
return f(*args,**kwargs)
return decorated
@decorator_name
def func():
return('func is running')
can_run=True
print(func())
# output: Function is running
can_run =False
print(func())
# Output: Function will not run
func():
return('func is running')
can_run=True
print(func())
# output: Function is running
can_run =False
print(func())
# Output: Function will not run