Python基础知识7:生成器和迭代器、递归
2017-12-17 00:00
609 查看
1、迭代器:
任何可以用 for in 来迭代读取的都是迭代容器,例如lists、tuples、sets、files、dict、str、生成器等。这些容器中的元素可以逐个地迭代获取。
以下为一个简单的迭代器:
list=[1,2,3,4,5]
for i in list:
print(i)
执行结果:
2、生成器
生成器与普通函数的区别
生成器是由函数创造的,类似于装饰器,都是在函数上面加上一个东西;而其关键词就是yield,当python看到函数中有yield时,就会将一个普通函数变成一个 generator生成器函数。
yield 语句的功能: 保存上次执行的位置,下次执行时,直接从这个位置开始,而不是一次生成全部的循环。一个函数或者子程序都只能 return 一次,但是一个生成器能暂停执行并返回一个中间的结果
案例1:正常的普通函数执行def func():#创建普通函数
print("start")
return 123
func() #执行函数,打印出来start执行结果:
案例2:正常的普通函数执行,并调用返回值def func():#创建普通函数
print("start")
return 123
ret=func() #执行函数,打印start
print(ret)#将函数值打印出来,打印函数返回值123执行结果为:
案例3:增加yield,变成生成器。第一次执行yield后会挂起函数。因此当调用下面的函数时执行结果为空def func():#创建普通函数
print("start")
yield 1#第一次执行yield后,会挂起函数
yield 2
yield 3
return 123
func() #执行函数目前执行结果为空。可以打印下函数的返回值看下,是一个生成器
案例4:当执行循环时,才会进函数取值。当有循环执行时,会在上次的结果的基础上依次往下执行;
案例5:调用生成器:可以用next控制,每次执行到yield挂起,只取yield之前的内容
生成器函数在每次暂停执行时,函数体内的所有变量都将被封存(freeze)在生成器中,并将在恢复执行时还原,并且类似于闭包,即使是同一个生成器函数返回的生成器,封存的变量也是互相独立的。 def func():#创建普通函数
print("start")
yield 1
print("a")
yield 2
print("b")
yield 4
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)执行结果:
设置了三个yield,可以调用4次。每个yield执行后挂起,只返回yield之前的内容。在一个生成器中,如果没有return,则默认执行到函数完毕时返回StopIteration。如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。def func():#创建普通函数
print("start")
yield 1#增加yield
print("a")
yield 2
print("b")
yield 3
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)执行结果:
如果第五次就会出错。
def func():#创建普通函数
print("start")
yield 1#增加yield
print("a")
yield 2
print("b")
yield 3
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)
r5=ret.__next__()#因为已经无yiled,则报错
print(r5)执行结果:
案例6:[b]生成器需要用迭代器来取数。如下为先使用next取数案例。[/b]
每次都从上次挂起的地方继续执行,一直到下一次的yield。def myrange(arg):
start=0
while True:
yield start
start+=1
ret=myrange(10)
r1=ret.__next__()#进入函数找到yield,执行完挂起
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)执行结果:
案例7:增加控制条件def myrange(arg):
start=0
while True:
if start>arg:
return
yield start
start+=1
ret=myrange(3)
r1=ret.__next__()#进入函数找到yield,执行完挂起,把start赋值给r1
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)
r3=ret.__next__()#执行第三次循环
print(r3)
r4=ret.__next__()#执行第四次循环
print(r4)
执行结果:
案例8:使用迭代器来代替next取数def myrange(arg):
start=0
while True:
if start>arg:
return
yield start
start+=1
ret=myrange(3)
for item in ret:
print(item)执行结果:
案例9:迭代器取每个元素#生成器应用案例:
def flatten(nested):
try:
if isinstance(nested, str):# 如果是字符串,转移到TypeError。
raise TypeError #引发异常
for sublist in nested:
for element in flatten(sublist):#把sublist传递给nested,先执行完flatten
print('got:', element)
except TypeError:#每次执行flatten时都会执行此函数
yield nested
L = ['aaadf', [1, 2, 3], 20, 40, [55, [66, [88, [99]], 'ddf'], 7]]
for i in flatten(L):
print(i)
执行结果:
3、递归函数
案例10:递归案例,return的值会依次传递def d():
return '123'
def c():
r=d()
return r
def b():
r=c()
return r
def a():
r=b()
print(r)
a()执行结果为123
案例11:递归实现阶乘:实现1*2*3*.....7def fun(num):
if num==1:
return 1
return num*fun(num-1)
x=fun(7)
print(x)执行结果:5040
参考网页: http://python.jobbole.com/87805/
案例链接:https://pan.baidu.com/s/1eSAjasM 密码:vblf
任何可以用 for in 来迭代读取的都是迭代容器,例如lists、tuples、sets、files、dict、str、生成器等。这些容器中的元素可以逐个地迭代获取。
以下为一个简单的迭代器:
list=[1,2,3,4,5]
for i in list:
print(i)
执行结果:
2、生成器
生成器与普通函数的区别
生成器是由函数创造的,类似于装饰器,都是在函数上面加上一个东西;而其关键词就是yield,当python看到函数中有yield时,就会将一个普通函数变成一个 generator生成器函数。
生成器(generator)概念:
生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束。yield 语句的功能: 保存上次执行的位置,下次执行时,直接从这个位置开始,而不是一次生成全部的循环。一个函数或者子程序都只能 return 一次,但是一个生成器能暂停执行并返回一个中间的结果
案例1:正常的普通函数执行def func():#创建普通函数
print("start")
return 123
func() #执行函数,打印出来start执行结果:
案例2:正常的普通函数执行,并调用返回值def func():#创建普通函数
print("start")
return 123
ret=func() #执行函数,打印start
print(ret)#将函数值打印出来,打印函数返回值123执行结果为:
案例3:增加yield,变成生成器。第一次执行yield后会挂起函数。因此当调用下面的函数时执行结果为空def func():#创建普通函数
print("start")
yield 1#第一次执行yield后,会挂起函数
yield 2
yield 3
return 123
func() #执行函数目前执行结果为空。可以打印下函数的返回值看下,是一个生成器
def func():#创建普通函数 print("start") yield 1#第一次执行yield后,会挂起函数 yield 2 yield 3 return 123 ret=func() #执行函数 print (ret)执行结果如下,为生成器:
案例4:当执行循环时,才会进函数取值。当有循环执行时,会在上次的结果的基础上依次往下执行;
def func():#创建普通函数 print("start") yield 1#取第一次循环,并且挂起,把值赋给i yield 2 yield 4 return 123 ret=func() #执行函数 for i in ret: print('i',i)执行结果:
案例5:调用生成器:可以用next控制,每次执行到yield挂起,只取yield之前的内容
生成器函数在每次暂停执行时,函数体内的所有变量都将被封存(freeze)在生成器中,并将在恢复执行时还原,并且类似于闭包,即使是同一个生成器函数返回的生成器,封存的变量也是互相独立的。 def func():#创建普通函数
print("start")
yield 1
print("a")
yield 2
print("b")
yield 4
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)执行结果:
设置了三个yield,可以调用4次。每个yield执行后挂起,只返回yield之前的内容。在一个生成器中,如果没有return,则默认执行到函数完毕时返回StopIteration。如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。def func():#创建普通函数
print("start")
yield 1#增加yield
print("a")
yield 2
print("b")
yield 3
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)执行结果:
如果第五次就会出错。
def func():#创建普通函数
print("start")
yield 1#增加yield
print("a")
yield 2
print("b")
yield 3
print("c")
return 123
ret=func() #执行函数
r1=ret.__next__()#进入函数找,执行到第一个yield,挂起,仅获取之前的数据
print(r1)
r2=ret.__next__()#接着上次执行的位置,执行到第二个yield,挂起
print(r2)
r3=ret.__next__()#接着上次执行的位置,执行到第三个yield,挂起
print(r3)
r4=ret.__next__()#进入上次执行的位置,执行print("c")
print(r4)
r5=ret.__next__()#因为已经无yiled,则报错
print(r5)执行结果:
案例6:[b]生成器需要用迭代器来取数。如下为先使用next取数案例。[/b]
每次都从上次挂起的地方继续执行,一直到下一次的yield。def myrange(arg):
start=0
while True:
yield start
start+=1
ret=myrange(10)
r1=ret.__next__()#进入函数找到yield,执行完挂起
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)执行结果:
案例7:增加控制条件def myrange(arg):
start=0
while True:
if start>arg:
return
yield start
start+=1
ret=myrange(3)
r1=ret.__next__()#进入函数找到yield,执行完挂起,把start赋值给r1
print(r1)
r2=ret.__next__()#上次挂起的地方,继续执行,直到下一个yield后再挂起
print(r2)
r3=ret.__next__()#执行第三次循环
print(r3)
r4=ret.__next__()#执行第四次循环
print(r4)
执行结果:
案例8:使用迭代器来代替next取数def myrange(arg):
start=0
while True:
if start>arg:
return
yield start
start+=1
ret=myrange(3)
for item in ret:
print(item)执行结果:
案例9:迭代器取每个元素#生成器应用案例:
def flatten(nested):
try:
if isinstance(nested, str):# 如果是字符串,转移到TypeError。
raise TypeError #引发异常
for sublist in nested:
for element in flatten(sublist):#把sublist传递给nested,先执行完flatten
print('got:', element)
except TypeError:#每次执行flatten时都会执行此函数
yield nested
L = ['aaadf', [1, 2, 3], 20, 40, [55, [66, [88, [99]], 'ddf'], 7]]
for i in flatten(L):
print(i)
执行结果:
3、递归函数
案例10:递归案例,return的值会依次传递def d():
return '123'
def c():
r=d()
return r
def b():
r=c()
return r
def a():
r=b()
print(r)
a()执行结果为123
案例11:递归实现阶乘:实现1*2*3*.....7def fun(num):
if num==1:
return 1
return num*fun(num-1)
x=fun(7)
print(x)执行结果:5040
参考网页: http://python.jobbole.com/87805/
案例链接:https://pan.baidu.com/s/1eSAjasM 密码:vblf
相关文章推荐
- python 迭代器、生成器基础知识
- Python菜鸟之路:Python基础-生成器和迭代器、递归
- Python基础教程----迭代器和生成器,递归,八皇后(2)
- python-基础知识之生成器
- Py修行路 python基础 (十一)迭代器 与 生成器
- python基础----迭代器、生成器、协程函数及应用(面向过程实例)
- Python高手之路【九】python基础之迭代器与生成器
- 基础知识回顾——迭代器和生成器
- python 基础(四) 正则,递归 生成器
- Python基础-迭代器和生成器
- python递归、迭代器和生成器在算法中的运用
- Python基础知识之迭代器
- python基础之生成器迭代器
- 【脚本语言系列】关于Python基础知识迭代器,你需要知道的事
- Python基础02--迭代器、生成器、列表解析
- python基础之迭代器和生成器
- Python基础知识之生成器
- python基础:迭代器与生成器
- python基础教程总结8——特殊方法,属性,迭代器,生成器,八皇后问题
- python-基础知识之三元表达式、列表推导式、生成器表达式