1,迭代器
'''
1.什么是迭代器
器:工具
迭代:是应该重复的过程,但每次重复都是基于上次的结果而来names=["egon",'lqz','yj']
count = 1
while count < len(names):
print(names[count])
count+=1 把列表里的值一个一个取了出来
迭代器:就是一种不依赖索引的取值工具2.为何要有迭代器
特性: 1.是用一种通用的迭代取值方案 2.惰性计算,节省内存3.如何使用迭代器'''
# 1.引入
dic = {'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()# 相当于引入了一个迭代器 赋值给另一个变量
res = dic_iterator.__next__()# 这个变量就变成了一个迭代器 引用其内置方法__next__顾名思义下一个
print(res)
while True:
try:
res = dic_iterator.__next__()# 可以写入一个循环 循环取值
print(res)
except StopIteration:# 要注意的是因为这是一个死循环 当容器内无值可取时 会报错 这个时候就要用到捕捉错误的语法
break
# 二:可迭代对象与迭代器对象
# 2.1 内置有__iter__方法的类型称之为:可迭代的对象/类型
# 1、字典dict
# 2、集合set
# 3、文件对象(也是迭代器对象)
# 4、字符串str
# 5、列表list
# 6、元组tuple
# 2.2 迭代器对象: 内置有__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循环的工作原理
dic = {"name":"egon", 'age':18, 'gender':"male"}
# dic_iterator = dic.__iter__()
# while True:
# try:
# res = dic_iterator.__next__()
# print(res)
# except StopIteration:
# break
# for k in dic: # 上面多行的代码完成的功能 用for循环两行就搞定了 他其实是做了一个简化的过程 可以看下方的解析
# 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('='*20)
# dic_iterator = dic.__iter__()
# while True:
# try:
# res = dic_iterator.__next__()
# print(res)
# except StopIteration:
# break # 这里就发现同一迭代器中已经无值可取
# 示例2:
# dic = {"name": "egon", 'age': 18, 'gender': "male"}
# for k in dic: # dic.__iter__()
# print(k)
#
# for k in dic: # dic.__iter__() # 如果是用了两个for循环就可以连续迭代两次 这是因为每次写一个for循环就会生成一个新的迭代器对象
# print(k)
2,自定义迭代器
# 上面一章所运用的迭代器都是基于已经有的可迭代对象,这样做对内存的使用并没有上面实质性的改善
# 这里就要自定义迭代器(生成器)来实现惰性计算,从而达到节省内存的效果
# 1、什么是生成器
# 但凡是函数内出现了yield关键字,调用函数将不会执行函数体代码,会得到一个返回值,该返回值
# 就是我们自定义的迭代器,称之为生成器
# def func():
# print("hello1")
# yield 111
# print("hello2")
# yield 222
# print("hello3")
# yield 333
#
#
#
# g = func()
# print(g)
# res=next(g) # 生成器本质就是迭代器 这里的g就是一个迭代器对象,用next方法来启动它
# print(res) # 得到迭代到的返回值111
#
# res=next(g)
# print(res) # 得到迭代到的返回值222
#
# res=next(g)
# print(res) # 得到迭代到的返回值333
#
# next(g) # 没有返回值就报错了
# 2、yield VS return
# (1)相同点:都可以用来返回值
# (2)不同点:
# return只能返回一次值,函数就立即结束了
# yield能返回多次值,yield可以挂起(暂停)函数
# 案例
# def func():
# res=0
# while True:
# res+=1 # 这里写一个死循环来生成无数个数
# yield res # 每循环一次就返回一次 然后暂停 等待下次调用再返回
#
# for i in func(): # 用for循环来调用func这个函数,i用来取返回值
# print(i)
# 总结迭代器的优缺点
# 优点:
# 1、是一种通用的迭代取值方案
# 2、惰性计算,节省内存
# 缺点:
# 1、取值不如索引、key的取值方式灵活
# 2、取值是一次性的,只能往后取,不能预估值的个数
def ra(x,y,z=1):# 自定义一个range功能(自定义生成器),三个参数想x(起始位置),y(结束位置),z(步长)
while x
yield x# 先返回起始位置的数
x += z# 按照步长进行累加
g = ra(1,15,3)
for iin g:
print(i)
# 计算结果:
# 1
# 4
# 7
# 10
# 13
3,面向过程
'''
面向过程:
核心是’过程‘二字,过程指的是做事的步骤
也就是先干什么,再干什么。。。。
好比在设计一条条流水线
优点:
可以把复杂的问题流程化,变简单
缺点:
牵一发而动全身,扩展性差
应用场景:脚本,框架'''
4,生成式
# 1.生成列表
l = []
for iin range(5):
l.append(i)
print(l)# 利用for循环按部就班的写入
# 1. 列表生成式
l = [ifor iin range(5)]# 一行代码搞定了上面三行代码,第一个i可以结合前面的l = 一起看,意思就是l.append(i)
print(l)
l = [ifor iin range(5)if i>2]# 也可以在后面加判断
print(l)
names=['lqz_sb','yj_sb','jason_sb','egon']
l=[namefor namein namesif name.endswith('sb')]# 加上判断可以取出特定字符
print(l)
# 2、集合生成式
# res={i for i in range(5)}
# print(res)
# 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))
# print(next(res))
# print(next(res))
# nums=(i for i in range(200000)) # 做一个累加操作
# res=sum(nums) # 直接使用sum方法吧每次生成出来的值加到一起
# print(res)
with open('01 迭代器.py', mode='rt', encoding='utf-8')as f:# 对文件内的字符个数进行一个计算
# 1 data=f.read() # 如果文件很大直接读取会对内存造成负担
# print(len(data)) # 2202
# 2 res=0
# for line in f: # 利用for循环一行一行的读取
# res+=len(line) # 累加读取的长度
# 3 res = sum((len(line) for line in f)) # 利用生成器表达式 一行代码解决 在sum方法内生成读取到每行的长度 累加
res =sum(len(line)for linein f)# 可以去掉一个括号 依然可以表达
print(res)
5,内置函数
# print(abs(-1)) # 取绝对值
# print(all([True,11,0])) # 逻辑门‘与’操作
# print(all([]))
# print(any([True,False,0])) # 逻辑门’或‘操作
# print(any([]))
# print(callable(len)) # 判断语句是否可读
# print(chr(90)) # 根据ASCLL码表的字符与其编号的关系进行转换chr就是编号转字符
# print(ord('Z')) # 字符转编号
# l=[1,2,3]
#
# print(dir(l)) # 查看此类型中的内置方法
print(divmod(10,4))# 取商取余操作
res=eval('{"k1":111}\n')
print(res['k1'])# 把原本是字符串变成了字典 可以用于文件的读写 写入的时候写成字典的格式(实际上是字符串类型),读的时候利用eval方法输出成字典