1.使用字典进行分支
在Python中,函数本身也是一个对象,并且函数名作为函数的引用,因此,如果使用函数名时后面没有跟(),说明此时将函数作为一个对象使用,就可以对函数对象的引用进行传递,根据这一规则,可以通过字典对if-elif语句进行替换,如:
def add():
print("add value")
def update():
print("update value")
def delete():
print("delete value")
def query():
print("query value")
def exit_():
print("exit!")
# 使用if-elif语句
value = input("please a char:")
if value == 'a':
add()
elif value == "u":
update()
elif value == "d":
delete()
elif value == "q":
query()
elif value == "e":
exit_()
# 使用关键字创建一个字典,将函数对象的引用作为值,提示符作为key
functions = dict(a = add,u = update,d = delete, e = exit_,q = query)
v = input("please a char:")
functions[v]()
2.生成器函数和生成器表达式
生成器函数(generator)、生成器(generator iterator)和yield语句
- 生成器函数(generator),是包含一个yield语句的函数,生成并返回一个生成器,即generator itertor,一般作为iterator用于for循环中,或者可以使用内置next()函数一次迭代一个值,不过这种方式很少遇到。
- 生成器(generator itertor),生成器函数创建并返回的对象。
- yield语句用于生成器函数中,当一个普通函数中使用了yield语句,则该函数就会变为生成器函数。
生成器函数和普通函数在执行时有区别,如果是普通函数,则每次执行时遇到return语句会返回并执行结束,再次执行时,则会重新开始执行。在执行生成器函数时,当执行到yield语句时返回,并记录当前的执行状态,包括局部变量、执行位置。当重新开始迭代时,开始从上次停止的位置开始,执行yield语句之后的内容。
下面是一个使用生成器函数的小例子:
def gen(max):
n = 0
while n < max:
yield n # 每次遍历,到这里都会返回,下一次便利时直接到了n = n +1 位置
n = n + 1
# 得到一个生成器s
s = gen(4)
# 对s进行遍历
for it in s:
print(it)
# 使用内置next()函数对生成器进行迭代,每次迭代一个值,如果迭代完成,再此迭代时会抛出StopIteration异常
print(next(s))
print(next(s))
print(next(s))
print(next(s))
print(next(s)) # StopIteration
生成器表达式(yield expression)
生成器表达式(yield expression)和列表内涵形式类似,不过生成器表达式语句包含在()中,形式如下:
(expression for item in iterable)
使用生成器函数和生成器表达式,都可以获取一个生成器,如下是两种类型获取生成器:
# 使用生成器函数
def get_item_dict(dict):
for key in dict:
yield key,dict[key]
# 使用生成器表达式
def get_item_dict_epr(dict):
return ((key,dict[key]) for key in dict)
if __name__ == "__main__":
d1 = dict(id=1,name="zhangsan",age=24,gender="男")
data_1 = get_item_dict(d1)
for s in data_1:
print(s)
data_2 = get_item_dict_epr(d1)
for s in data_2:
print(s)
# ('age', 24)
# ('id', 1)
# ('name', 'zhangsan
不管是使用yield表达式,还是使用生成器函数,都可以返回一个生成器,返回的生成器可以进行遍历,或者可以作为tuple,list的参数创建tuple和list。
除了内置next()
或__next__()
用于遍历,还提供了一个send()
方法,但是这几个方法用的很少。如果调用了生成器的send()方法,则send中的值被yield表达式的结果进行接收,有时也可以通过这个方法来控制遍历如:
def gen(max):
n = 0
while n < max:
receive = (yield n)
if receive is None:
n = n + 1
else:
n = receive
if __name__ == "__main__":
it = gen(5)
print(next(it))
print(next(it))
print(next(it))
it.send(0)
print(next(it))
print(next(it))
输出结果:
0
1
2
1
2