day15
一.迭代器
1.什么是迭代器?
器:工具
迭代:是一个重复的过程,但每次重复都是基于上一次的结果而来的
names=['egon','lqz','yj']
count = 0
while count < len(names):
print(names[count])
count+=1
迭代器:就是一种不依赖于索引的取值工具
2.为何要有迭代器?
特性:
1.是一种通用的迭代取值方案
2.惰性计算,节省内存
3.如何用迭代器?
引入:
dic = {'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()
res1 = dic_iterator.__next__()
print(res1)
res2 = dic_iterator.__next__()
print(res2)
res3 = dic_iterator.__next__()
print(res3)
dic_iterator.__next__() # StopIteration
while True:
try:
res=dic_iterator.__next__()
print(res)
except StopIteration:
break
可迭代对象与迭代器对象
可迭代的对象/类型:
内置有__iter__方法的类型
字典dict
集合set
文件对象(也是迭代器对象)
字符串str
列表list
元组tuple
迭代器对象:
内置有__next__方法,内置有__iter__方法
文件对象/句柄是迭代器对象
dic = {'name':'egon','age':18,'gender':'male'}
dic_iterator1 = dic.__iter__()
# dic.iterator1.__next__()
# print(dic_iterator1.__iter__().__iter__().__iter__() is dic_iterator1)
# dic_iterator2 = dic.__iter__()
for循环的工作原理
1.调用可迭代对象的__iter__方法,转换为迭代器对象
2.使用迭代器对象的__next__方法,执行循环体代码
3.循环往复,直到抛出异常,for循环会帮我们捕捉异常结束循环
dic={'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()
# while True:
# try:
# res=dic_iterator.__iter__()
# print(res)
# except StopIteration:
# break
for k in dic:
print(k)
"""
步骤1 dic_iterator = dic.__iter__()
步骤2 k=dic_iterator.__next__(),执行循环体代码
步骤3 循环往复,直到抛出异常,for循环会帮我们捕捉异常结束循环
"""
dic = {'name':'egon','age':18,'gender':'male'}
dic_iterator=dic.__iter__()
for k in dic_iterator:
print(k)
print(dic_iterator)
基于同一迭代器的重复取值,效果如何?
案例1:
取值完毕后,再取一次,需要重置迭代器
dic={'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()
while True:
try:
res=dic_iterator.__next__()
print(res)
except StopIteration:
break
print('<=============>')
dic_iterator = dic.__iter__()
while True:
try:
res=dic_iterator.__next__()
print(res)
except StopIteration:
break
案例2:
使用for循环,一次完全取值完毕后,不用重置
dic={'name':'egon','age':18,'gender':'male'}
for k in dic: # dic.__iter__()
print(k)
for k in dic: # dic.__iter__()
print(k)
二.生成器
自定义迭代器来实现惰性计算,从而达到节省内存的效果
1.什么是生成器
但凡是函数内出现了yield关键字,调用函数将不会执行函数体代码,会得到一个返回值,该返回值就是我们自定义的迭代器,称之为生成器
def func():
print('hello1')
yield 111
print('hello2')
yield 222
print('hello3')
yield 333
g = func()
print(g)
res=next(g)
print(res)
res=next(g)
print(res)
res=next(g)
print(res)
2.yield vs return
相同点: 都可以用来返回值
不同点:
return只能返回一次值,函数就立即结束了
yield能返回多次值,yield可以挂起函数
案例:
def func():
res = 0
while True:
res+=1
yield res
g = func()
for i in g:
print(i)
总结迭代器的优缺点:
优点:
1.是一种通用的迭代取值方案
2.惰性计算,节省内存
缺点:
1.取值不如索引,key的取值方式灵活
2.取值是一次性的,只能往后取,不能预估值的个数
自定义range:
def my_range(start,stop,step=1):
while start < stop:
yield start
start+=step
for i in my_range(1,5,2):
print(i)
三.面向过程编程
面向过程:
核心是'过程'二字,过程指的就是做事的步骤
也就是先干什么,在干什么,后干什么
基于该思想写程序就好比设计一条条的流水线
优点:
可以把复杂的问题流程化,简单化
缺点:
牵一发而动全身,扩展性差
应用场景:
脚本程序
设计框架
四.生成式
1.列表生成式
l = [i**2 for i in range(5) if i > 2]
print(l)
names = ['lxx_sb','zxx_sb','lisi']
l=[name for name in names if name.endswith('sb')]
print(l)
2.集合生成式
res = {i for i in range(5)}
print(res,type(res)) # {0, 1, 2, 3, 4} <class 'set'>
3.字典生成式
res = {f'k{i}':i**2 for i in range(5)}
print(res)
4.生成器表达式
res = (i for i in range(5))
print(res,type(res))
print(next(res))
print(next(res))
print(next(res))
print(next(res))
nums = (i for i in range(200000))
res=sum(nums)
print(res)
案例:
with open('user.txt','r',encoding='utf-8')as f:
# 方式1:文件过大不适用
# data = f.read()
# print(len(data))
# 方式2:适用于读取大文件,但代码不够简洁
# res=0
# for line in f:
# res+=len(line)
# 方式3:一行搞定
# res=sum((len(line) for line in f))
res = sum(len(line) for line in f)
print(res)
五.内置函数
abs:取绝对值
print(abs(-1))
all:括号内的参数全为真,返回True,一个为假,返回False
# print(all([True,11,0]))
# print(all([])) # 参数值为空,返回True
any:任意一个函数为真,返回True,全为假,返回False
# print(any([True,False,0]))
# print(any([])) # 参数值为空,返回False
callable:判断括号内的参数是否可调用
print(callable(len))
chr :根据ASCII编码表,返回括号内数字对应的符号
ord:根据ASCII编码表,返回括号内符号对应的数字
# print(chr(90))
# print(ord('Z'))
dir:函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;带参数时,返回参数的属性、方法列表。如果参数包含方法__dir__(),该方法将被调用。如果参数不包含__dir__(),该方法将最大限度地收集参数信息
# l=[1,2,3]
# print(dir(l))
divmod(m,n):返回m//n的值,及m%n的值
# print(divmod(10,3))
eval:
1.函数用来执行一个字符串表达式,并返回表达式的值
2.字典保存在文件中是字符串形式,可以使用eval转换为字典形式
res=eval('{"k1":111}\n')
print(res['k1'])