迭代器,生成器与内置函数

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}\n')
print(res['k1'])#可以在字符串模式下
#实现运行一些我们需要转换后才能实现的功能。

posted @ 2020-07-22 16:31  Orange-ONE  阅读(85)  评论(0编辑  收藏  举报