什么是迭代器?
迭代: 更新换代的过程, 也是一个重复的过程, 每一次的迭代都必须基于上一次的结果 (迭代与迭代之间必须要有关系)
迭代器: 迭代取值的工具
为什么要用迭代器?
迭代器给提供了一种不依赖于索引取值的方式
需要迭代取值的数据类型: 字符串, 列表, 元组, 字典, 集合
- l = [1,2,3,4]
- n = 0
- while n <len(1):
- print(l[n])
- n += 1
- # 重复 +, 每次迭代都是基于上一次的结果而来的
可迭代对象
只要内置有__iter__方法的都叫做可迭代对象
补充: 针对双下划线开头双下划线结尾的方法, 推荐读双下 + 方法名
基本数据类型中可迭代对象的: str,list,tuple,dict,set,
文件对象 (执行内置的__iter__之后还是本身, 没有任何变化), 文件对象本身就是迭代器对象.
可迭代对象执行内置的__iter__方法得到就是该对象的迭代器对象
迭代器取值
迭代器对象:
1, 内置有__iter__方法
迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身
2, 内置有__next__方法
迭代器对象一定是可迭代对象, 而可迭代对象不一定是迭代器对象
可迭代对象: 内置有__iter__方法的
迭代器对象: 既内只有__iter__也内置有__next__方法
迭代取值:
优点:
1, 不依赖于索引取值
2, 内存中永远只占一份空间, 不会导致内存溢出
缺点:
1, 不能够获取指定的元素
2, 取完之后会报 stopiteration
- d = {
- 'name':'moly','password','123','hobby':'read'
- # 将可迭代对象 d 转换成迭代器对象
- iter_d = d.__iter__()
- # 迭代器对象的取值必须用__next__
- print(iter_d.__next__()) #name
- print(iter_d.__next__()) #password
- print(iter_d.__next__()) #hobby
- print(iter_d.__next__()) #取完了, 报错 StopIteration 异常
迭代器取值的特点: 只能往后依次取, 不能后退.
for 循环后面的 in 关键字, 跟的是一个可迭代对象
for 循环内部的本质
1, 将 in 后面的对象调用__iter__转换成迭代器对象
2, 调用__next__迭代取值
3, 内部有异常捕获 stopiterration, 当__next__报这个错, 自动结束循环
生成器
它的本质就是一个迭代器
yield: 函数内如果有 yield 关键字, 那么加括号执行函数的时候并不会触发函数体代码的运行
后面跟的值就是调用迭代器__next__方法你能得到的值, 它既可以返回一个值, 也可以返回多个值, 并且多个值也是按照元组的形式返回
当函数内有 yield 关键字的时候, 调用该函数不会执行函数体代码, 而是将函数变成生成器
- def my_range(start,end,step):
- while start < end:
- yield start
- start += step
- for i in my_range(1,10,2):
- print(j)
yield 和 return
yield
1, 帮你提供了一种自定义生成器方式
2, 会帮你保存上一次函数调用的状态
3, 可以返回值
与 return 之间的相同点
都可以返回值, 并且都可以返回多个值
不同点: 1.yield 可以返回多次值, 而 return 只能返回依次函数立即结束
2,yield 还可以接受外部传入的值
生成器表达式
- res = (i for i in range(1,10) if i != 4) #生成器表达式
- print(res)
优点: 只占一行空间
生成器不会主动执行任何一行代码, 必须通过__next__触发代码的运行
面向过程编程: 就类似于设计一条流水线
好处: 将复杂的问题流程化, 从而简单化
坏处: 可扩展性比较差, 一旦需要修改, 整体都会受到影响
注册功能
- #1. 获取用户输入
- def get_info():
- while True:
- username = input(">>>:").strip()
- if not username.isalpha(): #判断字符串不能包含数字
- print('不能包含数字')
- continue
- password = input('>>>:').strip()
- confirm_password = input("confirm>>>:").strip()
- if password == confirm_password:
- d = {
- '1':'user'
- '2':'admin'
- }
- while True:
- print("""
- 1 普通用户
- 2 管理员
- """)
- choice = input('please choice user type toregister>>>:').strip()
- if choice not in d:continue
- user_type = d.get(choice)
- operate_data(username,password,user_type)
- break
- else:
- print('两次密码不一致')
- #处理用户信息
- def operate_data(username,password,user_type):
- res = '%s|%s|%s\n'%(username,password,user_type)
- save_data(res,'userinfo.txt')
- #存储到文件中
- def save_data(res,file_name):
- with open(file_name,'a',encoding='utf-8') as f:
- f.write(res)
- def register():
- get_info()
- register()
- View Code
请写出一下代码的执行结果并解释.
- def multipliers():
- return [lambda x, i=i: i*x for i in range(4)]
- # 0, 1, 2, 3
- # [func(x): return 0*x, func(x): return 1*x,
- # func(x): return 2*x, func(x): return 3*x, ]
- print([m(2) for m in multipliers()]) # [0, 2, 4, 6]
- # [func(x): return 0*2, func(x): return 1*2,
- # func(x): return 2*2, func(x): return 3*2, ]
- # [0, 2, 4, 6]
- # [6, 6, 6, 6]
- # 闭包函数的延迟绑定
- # 在内层函数执行时才会绑定变量 i
- def multipliers2():
- list1 = []
- for i in range(4):
- def func(x, i=i): #定义函数
- return x * i
- list1.append(func) #把函数名称传进去
- return list1
- print([m(2) for m in multipliers2()]) # [0, 2, 4, 6]
- View Code
来源: http://www.bubuko.com/infodetail-3124755.html