Python 迭代器-生成器-面向过程编程

时间:2023-03-08 23:32:58
Python 迭代器-生成器-面向过程编程
上节课复习:
1. 函数的递归调用
    在调用一个函数的过程中又直接或者间接地调用了函数本身称之为函数的递归
    函数的递归调用有两个明确的阶段:
      1. 回溯
        一层一层地调用本身
      注意:
        1.每一次调用问题的规模都必须有所减少
        2.必须有一个明确的结束条件或者进入递归的条件
      2. 递推
        往回一层一层的推算出结果 2. 二分法 3.三元表达式
res=条件成立情况下的返回值  if条件   else条件不成立情况下的返回值

4.列表生成式
[for i in range(10) if i > 3]

5.字典生成式
(i:i for in in range(10) if i>3)

6.匿名函数
  匿名函数的精髓在于没有名字,没有名字意味着只能调用一次就会被当做垃圾回收
lambda 参数1,参数2....:函数体代码

max([],key=lambda 参数1,参数2....:函数体代码)

理论性的知识:
1. 迭代器
  1.什么是迭代器
  迭代器指的是迭代取值的工具
  迭代是一个重复的过程,每一次重复都是基于上一次的结果而来
#单纯的重复不是迭代
 i=0
while True:
print(i)

#迭代:重复+每次重复都是基于上一次的结果而进行
 l=['a','b','c']
i = 0
while i < len(l):
print(l[i])
i+=1
2.为何要用迭代器
  迭代器提供了一种通用的且不依赖于索引的迭代取值方式 3.如何用迭代器
  1.可迭代的对象iterable: 但凡内置有__iter__方法的对象都称之为可迭代的对象
    可迭代的对象: str, list, tuple, dict, set, 文件对象
    执行可迭代对象下的__iter__方法,返回的值就是一个迭代器对象iterator
 dic={'x':1,'y':2,'z':3}
iter_dic=dic.__iter__()
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
print(iter_dic.__next__())
2.迭代器对象
  1.内置有__next__方法的对象,执行迭代器__next__方法可以不依赖索引取值
  2.又内置有__iter__方法的对象,执行迭代器__iter__方法得到的仍然是迭代器本身
  ps:
    1.迭代器对象一定是可迭代的对象,而可迭代的对象却不一定是迭代器对象
    2.文件对象本身就是一个迭代器对象   for本质应该称之为迭代器循环
  工作原理
  1.先调用in后面那个对象的__iter__方法,将其变成一个迭代器对象
  2.调用next(迭代器),将得到的返回值赋值给变量名k
  3.循环往复直到next(迭代器)抛出异常,for会自动捕捉异常然后结束循环
  ps:从for角度,可以分辨出但凡可以被for循环循环取值的对象都是可迭代的对象
 dic={'x':1,'y':2,'z':3}
for k in dic:
print(k)
3.迭代器总结
  优点:
    1.提供一种不依赖于索引的迭代取值方式
    2.同一时刻在内存中只存在一个值,更节省内存
  缺点:
    1.取值不如按照索引的方式灵活,(不能取指定的某一个值,而且只能往后取)
    2.无法预测迭代器的长度   2.生成器(自定义的一种迭代器)
    大前提: 生成器就是一种自定义的迭代器,本质就是迭代器
    但凡函数内包含yield关键字,调用函数不会执行函数体代码,会得到一个返回值,该返回值就是生成器对象
    会触发函数的执行,直到碰到一个yield停下来,并且将yield后的值当做本次next的结果返回
    了解: yield的表达式形式的应用 x=yield
 def dog(name):
print('狗哥 %s 准备开吃' %name)
food_list=[]
while True:
food=yield food_list # food=yield='肉包子'
print('%s 吃了 %s' %(name,food))
food_list.append(food) g=dog('alex') # 强调:针对表达式形式的yield的使用,第一步必须让函数先暂停到一个yield的位置,才能进行传值操作
# next(g) # 张开狗嘴,让生成器先暂停到yield的位置,准备接收外部传进来的值
res1=next(g) #g.send(None)
# print(res1) res2=g.send('屎包子') # 1. 先为当前暂停位置的yield赋值 2. next(生成器)直到再次碰到一个yield停下来,然后其的值当做本次next的结果
# print(res2) res3=g.send('肉包子')
# print(res3) res4=g.send('泔水')
print(res4)
    总结yield: 只能在函数内使用
    1. yield提供了一种自定义迭代器的解决方案
    2. yield可以保存函数的暂停的状态
    3.yield对比return
      1.相同点: 都可以返回值,值的类型与个数都没有限制
      2.不同点: yield可以返回多次值,而return只能返回一次值函数就结束了   3. 面向过程编程:
    核心是过程二字,过程指的就是解决问题的步骤,即先干什么再干什么后干什么....
    基于该思想编写程序就好比在设计一条流水线,是一种机械式的思维方式
    优点: 复杂的问题流程化,进而简单化
    缺点: 可扩展性差 代码操作:
1. 生成器表达式 2. 内置函数:
 abs()  取绝对值,负数变正数
all() 如果迭代器内所有值为真就返回True,否则为False(如果是空列表也为True)
any() 如果可迭代对象有一个值为真就返回True
bin() 返回一个整数 int 或者长整数 long int 的二进制表示
oct() 将一个整数转换成8进制字符串
hex() 将10进制整数转换成16进制,以字符串形式表示
bool() 除了0,空,None 为False,其他都为True
bytes() 转成bytes类型
callable() 判断是否为可调用函数,可调用返回True,不可调用返回False
chr() 以十进制对应ASCII码表返回出对应的字符
ord() 以字符对应ASCII码表返回出对应的十进制
dir() 查看一个对象.有哪些属性能够引用
divmod() 取几除以几返回(商,余)
enumerate() for循环中打印出来格式 索引,值
eval() 用来执行一个字符串表达式,并返回表达式的值
set() 可变集合
frozenset() 不可变集合
help() 用于查看函数或模块用途的详细说明
pow() pow(x,y,z) (x**y)%z x的y次方除以z取余
reversed() 函数返回一个反转的迭代器
round() 返回浮点数x的四舍五入值
slice() 主要用在切片操作函数里的参数传递
zip() 用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表。
如果各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同,利用 * 号操作符,可以将元组解压为列表。