# 函数迭代器 生成器 常用内置函数 ----- # 13

"""

函数知识点:

1.迭代器

 1 """
 2 1.什么是迭代器?
 3    迭代:更新换代(重复)的过程,每次的迭代都必须基于上一次的结果
 4    迭代器:迭代取值的工具,即更新换代的工具
 5 
 6 2.为什么要使用迭代器?
 7      迭代器可以为我们提供一个不需要索引的取值方式(__next__)
 8 
 9 3.需要迭代取值的数据类型有:
10       字符串
11       列表
12       元组
13       字典
14       集合
15 
16 ***** 内置__iter__方法的就是可迭代对象
17 4.如何使用
18      # 案例说明:
19 # 结论:重复 + 每次迭代都是基于上一次的结果而来的
20 """
21 '''
22 # 案例说明:
23 # 结论:重复 + 每次迭代都是基于上一次的结果而来的
24 # n = 1
25 # while True:
26 #     print(n)
27 #     n += 1
28 
29 s = 'hello'
30 n = 0
31 while n < len(s):
32     print(s[n])
33     n += 1
34 '''
35 # 数据类型
36 # 整型
37 n = 1
38 # 浮点型
39 f = 1.1
40 # 字符串
41 s = 'hello'
42 s.__iter__()
43 # 列表
44 l = [1,2,34]
45 l.__iter__()
46 # 元组
47 t = (1,2,34)
48 t.__iter__()
49 # 集合
50 s1 = {1,2,3,4}
51 s1.__iter__()
52 # 字典
53 d = {'name':'Jason'}
54 d.__iter__()
55 # 文件
56 f1 = open('xxx.txt','w',encoding='utf-8')
57 f1.__iter__()
58 # 通过数据类型加  .  的方式,测试其有无__iter__方法,即是否为可迭代对象?
59 # 符合要求的数据类型有
60 '''
61 需要迭代取值的数据类型有:
62       字符串
63       列表
64       元组
65       字典
66       集合
67 
68 ***** 内置__iter__方法的就是可迭代对象
69 '''
迭代器

2.可迭代器

 1 """
 2 ### 引入可迭代对象
 3 # 数据类型
 4 # 整型
 5 n = 1
 6 # 浮点型
 7 f = 1.1
 8 # 字符串
 9 s = 'hello'
10 s.__iter__()
11 # 列表
12 l = [1,2,34]
13 l.__iter__()
14 # 元组
15 t = (1,2,34)
16 t.__iter__()
17 # 集合
18 s1 = {1,2,3,4}
19 s1.__iter__()
20 # 字典
21 d = {'name':'Jason'}
22 d.__iter__()
23 # 文件
24 f1 = open('xxx.txt','w',encoding='utf-8')
25 f1.__iter__()
26 # 通过数据类型加  .  的方式,测试其有无__iter__方法,即是否为可迭代对象?
27 # 符合要求的数据类型有
28 '''
29 需要迭代取值的数据类型有:
30       字符串
31       列表
32       元组
33       字典
34       集合
35       文件
36 '''
37 """
38 """
39 ### 可迭代对象:
40        只有内置有__iter__方法的都叫做可迭代对象
41 "__iter__"
42 补充:针对双下划綫开头双下划线结尾的方法
43 推荐读法:双下+方法名
44 """
45 """
46 基本数据类型中,是可迭代对象得有:
47      str,list,dict,tuple,set,
48      + 文件对象(执行内置__iter__之后还是本身,没有任何变化);
49      注:文件对象本身就是迭代器对象
50 
51 ***** 可迭代对象执行内置的__iter__方法得到的就是该对象的迭代器对象
52 
53 """
可迭代器

3.迭代器对象 -- 迭代器取值

 1 """
 2 迭代器对象:
 3     1.内置有__iter__方法
 4     2.内置有__next__方法
 5     ps:
 6        1.迭代器一定是可迭代对象
 7        2.而可迭代对象不一定是迭代器对象
 8 
 9 迭代器取值:
10     "__next__"
11     特点: 1.只能往后依次取,不能后退
12 
13 # 案例说明:
14     1.可迭代对象调用__iter__转换成迭代器对象
15     2.调用__next__迭代取值
16     3.内部有异常捕获StopIteration(停止迭代),
17     ***** 4.结论:迭代器对象无论执行多少次__iter__方法得到的还是迭代器本身
18     5.# 错误原因:每次重新创建了一个迭代器
19 print(d.__iter__().__next__())  # name
20      处理方式:try...except...
21 """
22 '''
23 # 实例1:
24 l = [1,2,3,4,5,6,7]
25 # 生成一个可迭代对象   + .__iter__
26 iter_l = l.__iter__()
27 
28 # 迭代器取值 调用 __next__
29 print(iter_l.__next__())  # 1
30 print(iter_l.__next__())  # 2
31 print(iter_l.__next__())  # 3
32 print(iter_l.__next__())  # 4
33 print(iter_l.__next__())  # 5
34 print(iter_l.__next__())  # 6
35 print(iter_l.__next__())  # 7
36 
37 # 如果取完了,会报错  # StopIteration 停止迭代
38 print(iter_l.__next__())
39 '''
40 
41 
42 """
43 # 实例2
44 d = {'name':'jason','password':'123','hobby':'泡m'}
45 # 将可迭代对象d转换成迭代器对象
46 iter_d = d.__iter__()
47 # 迭代器对象的取值 必须用__next__
48 print(iter_d.__next__())  # name
49 print(iter_d.__next__())  # password
50 print(iter_d.__next__())  # hobby
51 # 取完了 报错StopIteration
52 print(iter_d.__next__())  
53 """
54 """
55 # 实例3
56 f1 = open('xxx.txt','r',encoding='utf-8')
57 print(f1)  # 值:<_io.TextIOWrapper name='xxx.txt' mode='r' encoding='utf-8'>
58 iter_f1 = f1.__iter__()  
59 print(iter_f1)  #值 <_io.TextIOWrapper name='xxx.txt' mode='r' encoding='utf-8'>
60 print(iter_f1 is f1)  # 值: True
61 
62 ***** 结论:迭代器对象无论执行多少次__iter__方法得到的还是迭代器本身
63 
64 # # print(f1 is f1.__iter__().__iter__().__iter__().__iter__())
65 """
66 # 常见逻辑错误
67 d = {'name':'jason','password':'123','hobby':'泡m'}
68 
69 # 错误原因:每次重新创建了一个迭代器
70 print(d.__iter__().__next__())  # name
71 print(d.__iter__().__next__())  # name
72 print(d.__iter__().__next__())  # name
73 """
74 补充:异常处理
75 try:
76 except:
77 实例:
78 d = {'name':'jason','password':'123','hobby':'泡m'}
79 iter_d = d.__iter__()
80 while True:
81     try:
82         print(iter_d.__next__())
83     except StopIteration as e:
84         print(e,'出现错误')
85         break
86         '''
87         值:
88         name
89         password
90         hobby
91         出现错误
92 
93         '''
94 """
迭代器对象 -- 迭代器取值

4.for循环的本质

 1 """
 2 ### :
 3 for循环内部的本质:
 4     1.将in后面的对象调用__iter__转换成迭代器对象
 5     2.调用__next__迭代取值
 6     3.内部有异常捕获StopIteration(停止迭代),当__next__报这个错,自动结束循环
 7 
 8 """
 9 
10 # 引出for循环
11 d = {'name':'jason','password':'123','hobby':'泡m'}
12 # for i in d:
13 #     print(i)
14 # for循环后面的in关键跟的是一个可迭代对象
15 '''
16 # 验证for循环本质1:
17 for i in 1:
18     pass
19 # 报错  'int' object is not iterable(int对象没有iter,即补课迭代的)
20 # 1.__iter__()  # 报错,语法错误
21 # iter(1)  # 'int' object is not iterable
22 '''
for循环的本质

1.2.3.4.迭代器总结

 1 """
 2 可迭代对象:内置有__iter__方法
 3 迭代器对象:既内置有__iter__,也内置有__next__方法
 4 
 5 迭代取值:
 6     优点:
 7        1.不依赖于索引取值
 8        2.内存中永远只占一份空间,不会导致内存溢出
 9     缺点:
10        1.不能获取指定元素
11        2.取完后会报StopIteration(停止迭代)错
12 """
13 # l = [1,2,3,4]
14 # # map 基于for的循环,给他传一个可迭代对象
15 # res = map(lambda x:x+1,l)
16 # print(res)
17 # # 值  <map object at 0x00000236BF1E7550>
18 # # python 3 取值,有优化,要一个取一个,不会占内存
19 # print(res.__next__())  # 2
20 # print(res.__next__())  # 3
21 # print(res.__next__())  # 4
22 # print(res.__next__())  # 5
23 # print(res.__next__())  # StopIteration
24 
25 # Python 2  直接返回一个列表[2,3,4,5]
26 # l = [1,2,3,4]
27 # res = map(lambda x:x+1,l)
28 # res  # 值[2,3,4,5]
29 
30 l1 = [1,2,3,4]
31 l2 = ['a','b','c']
32 print(zip(l1,l2))
33 res = zip(l1,l2)
34 print(res.__next__())  # (1, 'a')
35 print(res.__next__())  # (2, 'b')
36 print(res.__next__())  # (3, 'c')
37 print(res.__next__())  # StopIteration
迭代器总结

5.生成器--自定义迭代器

 1 """
 2 生成器:   用户自定义的迭代器,本质就是迭代器
 3 
 4 ps:
 5     # 1.函数内如果有 yield 关键字,加括号执行函数的时候并不会触发函数体代码的运行
 6     # 2.而是生成器初始化:即将函数变成迭代器
 7     # 3.yield 后边跟的值就是调用__next__方法你能得到的值
 8     # 4.yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
 9 """
10 def run():
11     print("first")
12     yield 1
13     print('sencond')
14     yield 3
15     print('thord')
16     yield 5,6
17     print('forth')
18     yield 7
19     print('sixth')
20     yield 9 # yield 后边跟的值就是调用__next__方法你能得到的值
21     yield
22 res = run()
23 # 1.函数内如果有 yield 关键字,加括号执行函数的时候并不会触发函数体代码的运行
24 # 2.而是生成器初始化:即将函数变成迭代器
25 
26 print(res)
27 print(res.__next__())
28 print(res.__next__())
29 print(res.__next__())
30 print(res.__next__())
31 print(res.__next__())
32 print(res.__next__())
33 print(res.__next__())
34 
35 """
36 first
37 1
38 sencond
39 3
40 thord
41 (5, 6)  # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
42 forth
43 7
44 sixth
45 9
46 None
47 StopIteration(报错,停止迭代)
48 """
生成器--自定义迭代器

6.range 功能--自定义

 1 '''
 2 print(range(1,10))  # 值 range(1, 10)
 3 for i in range(1,10,2):
 4     print(i)
 5 *********** range + (可迭代对象)
 6 '''
 7 '''
 8 for循环内部的本质:
 9     1.将in后面的对象调用__iter__转换成迭代器对象
10     2.调用__next__迭代取值
11     3.内部有异常捕获StopIteration(停止迭代),当__next__报这个错,自动结束循环
12 值:
13 1
14 3
15 5
16 7
17 9
18 '''
19 # 自定义range:
20 
21 def my_range(start,end,step):
22     while start < end:
23         yield start
24         start += step
25 res = my_range(1,10,2)
26 print(res)  # 值<generator object my_range at 0x00000143051D9258>
27 # print(res.__next__())
28 # print(res.__next__())
29 # print(res.__next__())
30 # print(res.__next__())
31 # print(res.__next__())
32 # print(res.__next__())
33 '''
34 # 值
35 1
36 3
37 5
38 7
39 9
40 StopIteration
41 '''
42 
43 for j in my_range(1,10,2):
44     print(j)
45 #
46 '''
47 1
48 3
49 5
50 7
51 9
52 '''
range 功能 -- 自定义

7.yield表达式形式(了解)

 1 """
 2 yield知识点:
 3 1.yield支持外界为其传参
 4     # 案例结论:
 5     # 1.当函数内有yield关键字的时候,调用函数不会执行函数体代码
 6     # 2.而是将函数变成生成器.
 7     # 3.yeild 左边变量传值,触发__next__方法
 8     # 4.必须先将代码运行至 yield 才能为其传值
 9 
10 """
11 # yield支持外界为其传参
12 def get_shop(shop):
13     print('买了一个%s'%shop)
14     while True:
15         shopping = yield
16         print('又买了一套%s'%shopping)
17 res = get_shop('cat')
18 print(res)  # <generator object get_shop at 0x0000018003739258>
19 # 结论:
20     # 1.当函数内有yield关键字的时候,调用函数不会执行函数体代码
21     # 2.而是将函数变成生成器.
22 # res.send('lll')  # can't send non-None value to a just-started generator 无法将非无值发送到刚启动的生成器
23 print(res.__next__())
24 res.send('xxx')  # yeild 左边变量传值,触发__next__方法
25 # 必须先将代码运行至 yield 才能为其传值
26 print(res.__next__())  # 又买了一套xxx
27 print(res.__next__())
yield 表达式形式

8.yield 与 return 的异同

 1 """
 2 yield:
 3    1.帮助提供一种自定义生成器方式(即存在 yield 就是生成器,反之就是函数)
 4    2.可以暂停函数的运行状态(必须通过__next__取值,一次取一个值)
 5    3.可以返回值
 6 
 7 与 return 的异同:
 8     相同:都可以返回值,且都可以返回多个
 9     不同:
10         yield 可以返回多次值,return 只能返回一次函数立即结束
11         yield 还可以接受外部传入的值
12 """
yield 与 return 异同

9.生成器表达式

 1 """
 2 # 列表生成式:   # list
 3 res = [i for i in range(1,10) if i != 4]
 4 print(res)  # [1, 2, 3, 5, 6, 7, 8, 9]
 5 
 6 # 生成器表达式  # tuple
 7 res1 = (i for i in range(1,100) if i != 4)
 8 print(res1)  # <generator object <genexpr> at 0x000002CCFD609258>
 9 
10 注:
11 1.# 生成器不会主动执行任何一行代码
12 2.# 必须通过__next__触发代码的运行
13 
14 print(res1.__next__())
15 print(res1.__next__())
16 print(res1.__next__())
17 print(res1.__next__())
18 print(res1.__next__())
19 
20 
21 
22 值:
23 1
24 2
25 3
26 5
27 ...
28 StopIteration
29 '''
30 
31 # 占内存   # file 文件
32 f = open('xxx.txt','r',encoding='utf-8')
33 data = f.read()
34 print(len(data))  # 57
35 f.close()
36 """
37 
38 
39 
40 with open('xxx.txt','r',encoding='utf-8')as f:
41     # n = 0
42     # for line in f:
43     #     f.read()
44     #     n += len(line)
45         # print(n)   # 57
46         res = (len(line) for line in f)
47 
48         # print(res)  # 8
49         print(res.__next__())
50         print(res.__next__())
51         print(res.__next__())
52         print(res.__next__())
53         print(sum(res))  #57
生成器表达式

9.生成器面试题

10.常用的内置函数

  1 # 1.abs()  # 求绝对值
  2 # print(abs(-11.11))  # 求绝对值
  3 
  4 # 2.all()  any()
  5 # all()  # 只要有一个为False就返回False
  6 # all()  # 只要有一个位True就返回True
  7 # l = [0,1,0]
  8 # print(all(l))  # 只要有一个为False就返回False
  9 # print(any(l))  # 只要有一个位True就返回True
 10 
 11 # 3 globals()  # 无论在哪 查看的都是全局名称空间  locals()  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
 12 # def index():
 13 #     username = '我是局部名称空间里面的username'
 14 #     print(locals())  # 当前语句在哪个位置 就会返回哪个位置所存储的所有的名字
 15 #     # 值{'username': '我是局部名称空间里面的username'}
 16 #     print(globals())  # 无论在哪 查看的都是全局名称空间
 17 #     '''
 18 #     值:
 19 #     {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001BD6205C2B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'E:/Python/项目/购物车面条版/day13.  1.迭代器  2.生成器  3.内置函数  4.面向过程思想/10.常用内置函数.py', '__cached__': None, 'index': <function index at 0x000001BD61F51E18>}
 20 #     '''
 21 # index()
 22 
 23 # # 4.bin() oct() hex()
 24 # print(bin(10))  # 转二进制 0b1010
 25 # print(oct(10))  # 转八进制 0o12
 26 # print(hex(10))  # 转十六进制 0xa
 27 # print(int('0b1010',2))  # 10进制转2进制 10
 28 
 29 # # 5.bool()
 30 # print(bool(1))  # True
 31 # print(bool(0))  # False
 32 
 33 # # 6.encode() # 设置底层字符编码 bytes() # 字节串(bytes)由多个字节组成,以字节为单位进行操作
 34 # s = 'hello'
 35 # print(s.encode('utf-8'))  # b'hello'
 36 # print(bytes(s,encoding='utf-8'))  # b'hello'
 37 
 38 # # 7.callable() 函数可调用,列表,不可调用
 39 # # 可调用的(可以加括号执行相应功能的)
 40 # a = 1
 41 # l = [1,2,3]
 42 # def index():
 43 #     pass
 44 # print(callable(a))  # False
 45 # print(callable(l)) # False
 46 # print(callable(index)) # True
 47 
 48 # # 8.char()  # 将数字转换成ascii码表对应的字符 ord() # 将字符按照ascii表转成对应的数字
 49 # print(chr(97))  # 将数字转换成ascii码表对应的字符  # a
 50 # print(ord('a'))  # 将字符按照ascii表转成对应的数字 # 97
 51 
 52 # # 9.dir获取当前对象名称空间里面的名字
 53 # l = [1,2,3]
 54 # print(dir(l))
 55 # # 值 ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
 56 # import text
 57 # print(dir(text))
 58 # # 值 ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
 59 # print(text.name)  # llx
 60 
 61 # # 10.divmod 分页器
 62 # print(divmod(101,10))  # (10, 1)
 63 # total_num,more = divmod(900,11)
 64 # if more:
 65 #     total_num += 1
 66 # print('总页数:',total_num)  # 总页数: 82
 67 
 68 # # 11.enumerate 枚举
 69 # l = ['a','b']
 70 # for i,j in enumerate(l,1):
 71 #     print(i,j)
 72 #     '值: 1 a   2 b'
 73 
 74 # # 12 eval  exec
 75 # s = """
 76 # print('hello baby~')
 77 # x = 1
 78 # y = 2
 79 # print(x + y)
 80 # """
 81 # # eval(s)  # 语法错误
 82 # exec(s)  # 值 hello baby~    3
 83 #
 84 # # eval不支持逻辑代码,只支持一些简单的python代码
 85 
 86 # s1 = """
 87 # print(1 + 2)
 88 # for i in range(10):
 89 #     print(i)
 90 # """
 91 # # eval(s1)  语法错误
 92 # exec(s1)  # 3 0 1 2 3 4 5 6 7 8 9
 93 
 94 # name = 'jason'
 95 # s2 = """
 96 # name
 97 # """
 98 # print(eval(s2))  # jason
 99 
100 # 13.format 三种玩法
101 # {}占位
102 # {index} 索引
103 # {name} 指名道姓
104 
105 # 14 help() 注释
106 # def login():
107 #     """
108 #     一起嗨皮
109 #     :return:
110 #     """
111 # print(help(login))
112 
113 #15 isinstance 后面统一改方法判断对象是否属于某个数据类型
114 # n = 1
115 # print(type(n))  # <class 'int'>
116 # print(isinstance(n,list))  # 判断对象是否属于某个数据类型 # False
117 
118 # pow() 平方
119 print(pow(2,3))   # 2**3
120 
121 
122 
123 print(round(3.9)) # 小数变整数
124 
125 
126 
127 """
128 面向对象需要学习的内置函数
129 1.classmethod
130 2.delattr
131 3.getattr
132 4.hasattr
133 5.insubclass 
134 6.property
135 7.repr
136 8.setattr
137 9.super
138 10.staticmethod
139 """
常用内置函数

11.面向过程编程

 1 """
 2 面向过程编程:就类似于设计一条流水线
 3     好处:
 4         将复杂的问题流程化 从而简单化
 5     坏处:
 6         可扩展性较差   一旦需要修改 整体都会受到影响
 7 """
 8 # 注册功能
 9 # 1.获取用户输入
10 def get_info():
11     while True:
12         username = input(">>>:").strip()
13         if not username.isalpha():  # 判断字符串不能包含数字
14             print('不能包含数字')
15             continue
16         password = input('>>>:').strip()
17         confirm_password = input("confirm>>>:").strip()
18         if password == confirm_password:
19             d = {
20                 '1':'user',
21                 '2':'admin'
22             }
23             while True:
24                 print("""
25                     1 普通用户
26                     2 管理员
27                 """)
28                 choice = input('please choice user type to register>>>:').strip()
29                 if choice not in d:continue
30                 user_type = d.get(choice)
31                 operate_data(username,password,user_type)
32                 break
33         else:
34             print('两次密码不一致')
35 
36 # 2.处理用户信息
37 def operate_data(username,password,user_type):
38     # jason|123
39     res = '%s|%s|%s
'%(username,password,user_type)
40     save_data(res,'userinfo.txt')
41 
42 # 3.存储到文件中
43 def save_data(res,file_name):
44     with open(file_name,'a',encoding='utf-8') as f:
45         f.write(res)
46 
47 def register():
48     get_info()
49 
50 register()
面向过程编程

"""

原文地址:https://www.cnblogs.com/llx--20190411/p/11191710.html