Python的小白们来了吗?
1. 迭代器
一,什么是迭代器
- 器=》工具
- 迭代:是一个重复的过程,但每次重复都是基于上一次的结果而来的
names=["egon",'lqz','yj']
count = 1
while count < len(names):
print(names[count])
count+=1
迭代器:就是一种不依赖于索引的取值工具
二,为何要有迭代器
特性:
- 1、是一种通用的迭代取值方案
- 2、惰性计算,节省内存
三,如何使用迭代器
3.1 引入
dic = {"name": "egon", 'age': 18, 'gender': "male"}
dic_iterator = dic.__iter__() #有__iter__用法的文件
res1 = dic_iterator.__next__() #有__next__用法的文件
print(res1)
3.2 可迭代对象与迭代器对象
内置有__iter__方法的类型称之为:可迭代的对象/类型
- 1、字典dict
- 2、集合set
- 3、文件对象(也是迭代器对象)
- 4、字符串str
- 5、列表list
- 6、元组tuple ==
迭代器对象: 内置有__next__方法、内置有__iter__方法
dic = {"name": "egon", 'age': 18, 'gender': "male"}
dic_iterator1 = dic.__iter__() # 将__iter__()之后的值需要赋值给某个变量
dic_iterator1.__next__() #一句__next__() 只执行一遍迭代操作。
print(dic_iterator1.__iter__().__iter__().__iter__() is dic_iterator1)
#————————》 True
#由上一行操作我们可以观察发现,不管你__iter__()多少遍,id永远都是相同的。
for 循环的工作原理
dic = {"name": "egon", 'age': 18, 'gender': "male"}
dic_iterator = dic.__iter__()
while True: #循环操作
try: #步骤3 循环往复,直到抛出异常,由try:会帮我们捕捉异常结束循环
res = dic_iterator.__next__()
print(res)
except StopIteration:#指定,异常抛出的是什么。
break
for k in dic: #用for循环我们可以以更简洁的话语去,实现迭代功能
print(k)
#我们可以吧for循环理解为迭代循环的,官方优化后的结果。
"""
步骤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)
基于同一个迭代器的重复取值效果是如何的。
dic = {"name": "egon", 'age': 18, 'gender': "male"}
dic_iterator = dic.__iter__()
while True:
try:
res = dic_iterator.__next__()
print(res)
except StopIteration:
break
print('第一个迭代循环')
print('='*20)
while True:
try:
res = dic_iterator.__next__()
print(res)
except StopIteration:
break
print('第二个迭代循环')
print('='*20)
# 示例2:
dic = {"name": "egon", 'age': 18, 'gender': "male"}
for k in dic: # dic.__iter__()
print(k)
print('第一个for循环')
print('='*20)
for k in dic: # dic.__iter__()
print(k)
print('第二个for循环')
执行结果:
name
age
gender
第一个迭代循环
====================
第二个迭代循环
====================
name
age
gender
第一个for循环
====================
name
age
gender
第二个for循环
四, 总结迭代器的优缺点
- 优点:
1、是一种通用的迭代取值方案
2、惰性计算,节省内存 - 缺点:
1、取值不如索引、key的取值方式灵活
2、取值是一次性的,只能往后取,不能预估值的个数
2. 生成器
一,什么是生成器
- 但凡是函数内出现了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)
next(g)
执行结果
<generator object func at 0x00000138E89FCCF0># generator 所以说本质就是迭代器
hello1
111 #返回值输出
hello2
222 #返回值输出
hello3
333 #返回值输出
#报错 停止迭代
Traceback (most recent call last):
File "E:/code/s15-day15/02 自定义迭代器.py", line 31, in <module>
next(g)
StopIteration
yield 对比 return
-
(1)相同点:都可以用来返回值
-
(2)不同点:return只能返回一次值,函数就立即结束了
yield能返回多次值,yield可以挂起函数def my_range(start, stop, step=1): while start < stop: yield start start += step for i in my_range(1,5,2): # 1 3 print(i) #自己写的简单range()
3. 面向过程编程
'''
面向过程:
核心是“过程”二字,过程指的就是做事的步骤
也就是先干什、再干什么、后干什么。。。
基于该思想写程序就好比设计一条条的流水线
优点:
可以把复杂的问题流程化,进而简单化
缺点:
牵一发而动全身,扩展性差
'''
4. 生成式
一, 列表生成式
l=[i**2 for i in range(11) if i > 2]
print(l) #在其中直接就可以运算,比较关系等等
names=['lqz_sb','yj_sb','jason_sb','egon']
l=[name for name in names if name.endswith('sb')]# 但是切记不可能有else
print(l)
结果:
[9, 16]
['lqz_sb', 'yj_sb', 'jason_sb']
二, 集合生成式
res={i for i in range(5)}
print(res)
结果:
{0, 1, 2, 3, 4}
三,字典生成器
res={f'k{i}': i**2 for i in range(5)}
print(res)
结果:
{'k0': 0, 'k1': 1, 'k2': 4, 'k3': 9, 'k4': 16}
四, 生成器表达式
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))
结果:
<generator object <genexpr> at 0x00000156F1A639E0> <class 'generator'>
#id地址
0
1
2
3
4
Traceback (most recent call last):
File "E:/code/s15-day15/04 生成式.py", line 27, in <module>
print(next(res))
StopIteration #终止迭代提示
四, 文件的特殊
- 文件对象本身就是
- 可迭代对象
- 迭代器对象
5. 内置函数
print(abs(-1)) #取绝对值操作
print(all([True,11,0]))
#取所有迭代对象的值,需要所有的值都为真,有一个为False结果就是False
print(all([]))
#如果是个空列表那么他的返回值就是True。
print(any([True,False,0]))
#取所有迭代对象的值,需要所有的值都为假,有一个为Ture结果就是True
print(any([]))
#如果是个空列表那么他的返回值就是False。
print(callable(len))# 看函数是否能被调用
print(chr(90))#把十进制数字转换成ACSLL表的字符
print(ord('Z'))#把ACSLL表的字符转换成十进制数字
l=[1,2,3]
print(dir(l))#判断这个列表,有什么属性。
print(divmod(10,3))#得到(商和余数)
res=eval('{"k1":111}
')
print(res['k1'])#可以在字符串模式下
#实现运行一些我们需要转换后才能实现的功能。