面试题:python2.0 和python3.0 中range有什么区别
1.对于python2.0中range()的生成原理----知识点来源柠檬班
def my_range(stop):
start=0
re=[]
while start< stop:
re.append(start)
start+=1
return re
print(my_range(10))
对于2.0版本,range中会定义一个空的列表,然后一次性生成所有的数,并放入列表中,这样是非常消耗内存的,当数字到达一定数量,比如9999就会报一个MemoryError内存不足的错误
针对这个解决方法可以使用xrange()
2.对于python3.0 中的range()
有一个__next__(),判断开始时间是否>=结束时间,如果满足条件抛出一个StopIteration的错误,
否则,start+=1 ,返回为start
用start记录上一次的位置,不会一次性生成所有,用到一个生成一个
python中判断一个函数是否为迭代器或可迭代对象或者是生成器
from collections.abc import Iterator,Iterable # 3.3版本引用时如果不带.abd会给一个红色提示,表示3.9这个版本该方法会禁用
import types
print(isinstance(range(5),Iterator)) # 迭代器
print(isinstance(range(5),Iterable)) # 可迭代对象
print(isinstance(range(5),types.GeneratorType)) # 生成器
知识来源---千峰python教程
可迭代对象:iterable
能被for 循环的,如序列:()字符串、列表、元组)和字典,内部含有iter()方法
迭代器:iterator
是特殊的可迭代对象,字符串、列表、元组等并不是迭代器,如果需要变成迭代器可以用iter()方法转换成迭代器
迭代器需要包含__iter__和__next__才能算是迭代器
生成器:generator 什么时候用什么时候取值
1.推导式使用的符号()
2.函数+yield
生成器的表达方式:
1.用()
案例:
t=(i for i in range(3)) # 生成器
print(isinstance(t,Iterator))
print(next(t)) # t.__next__() 同next(t)
print(next(t))
print(next(t))
print(next(t)) # 会抛出一个StopIteration
返回结果为:
True
0
1
2
2.用yield 使用在函数中:
1.1yield和return的区别:yield 是暂时退出本次循环后续还会进入,return是完全退出该循环
1.2需要用next()才会运行
def g():
for i in range(5):
yield i
print("这个是后面的内容")
g=g()
print(isinstance(g,types.GeneratorType)) # 是一个生成器
print(g) # 返回的是生成器对象
print(next(g)) # 会将yield 后的值返回
print(next(g)) # 第二次调用的时候,会从上一次yield后面继续运行,所以会打印print里面的内容
返回结果:
True
<generator object g at 0x03AB6A70>
0
这个是后面的内容
1
生成器额外的方法:
send(), close()
案例1
def g():
for i in range(5):
yield i
print("这个是后面的内容")
g=g()
g.close()
print(next(g)) #输出结果:StopIteration
案例2:
def g():
sum = 0
for i in range(5):
x= yield i # 接受外面传入的值
sum =x +i
print(f"输出结果为{sum}")
return "over" # 当生成器元素取完之后的报错信息,StopIterarion:over
g=g()
g.send(None) # 如果需要计算的话,那么第一个值必须为None
g.send(1)
g.send(2)
g.send(8)
g.send(2)
输出结果:
输出结果为1 #i 为0
输出结果为3 # i 为1
输出结果为10 # i 为 2
Traceback (most recent call last):
File "D:/lemonclass/kuran/new.py", line 23, in <module>
g.send(8)
StopIteration: over
生成器的应用:多任务切换
def study():
for i in range(3):
print(f"在学习中--->{i}")
yield
def listen_music():
for i in range(3):
print(f"在听歌中--->{i}")
yield
def wechat():
for i in range(3):
print(f"在聊天中--->{i}")
yield
s=study()
l=listen_music()
w=wechat()
try: # 防止迭代超出之后报错StopIteration
while True:
next(s)
next(l)
next(w)
except:
pass
输出结果:
在学习中--->0
在听歌中--->0
在聊天中--->0
在学习中--->1
在听歌中--->1
在聊天中--->1
在学习中--->2
在听歌中--->2
在聊天中--->2