迭代器以及生成器

本文介绍了迭代器和生成器的相关知识。迭代器可用于对不支持索引取值的对象进行取值,具有不依赖索引、不占内存等优点,但也有不能取指定元素等缺点。生成器是用户自定义的迭代器,通过yield关键字定义,取值方式与迭代器相同,且yield有独特特点。

一:迭代器:

【1】

迭代概念:

(1)即是重复的过程

(2)每次迭代的结果都是下次迭代的初始值

例如:

# PS:不是跌代的过程 虽然重复 但是每次迭代都是以单独的不是以上次的值作为初始值
n = 0
while True:
    print(n)

# PS:迭代
number = [1,2,3,4]
conut = 0
while conut < len(l):
        print(conut)
        conut+=1  

 

【2】

(1)迭代的作用:

  (1)对于字符串 列表 元组可以通过索引取值

  (2)字典 集合 文件类型不支持索引取值 可以通过迭代对其进行取值

 

(2) 可迭代对象:

定义:内置有__iter__,可以称之为可迭代对象

例如:

n = 1                                                               # 不支持__iter__、

name = 'Hello world'     .__iter__()                                # 支持__iter__

number = [1,2,3,4]    .__iter__()                                   # _支持__iter__

user_info = {'name':'SR','age':18}.__iter__()                        # 支持__iter__

s = (1,23,34,56).__iter__()                                         # 支持__iter__

f = {1,2,3,4,} .__iter__()                                          #支持__iter__

file = open('test.txt','w',encoding='utf-8').__iter__()             # 支持__iter__
可迭代对象

总结:字符串 列表 字典 集合 元组 文件

 

(3)迭代器对象:

定义:

  (1)内置有__iter__ 

  (2)内置有__next__, 可以称之为迭代器对象

PS:迭代器对象一定是可迭代对象 可迭代对象不一定是迭代器对象

 

取值:

基本定义方式:变量名.__next__用来进行取值

例如:

number = [1,2,3,4]
res = number.__iter__() # 变成可迭代对象
print(res)              # <list_iterator object at 0x00000000022F7358> 取出来一串地址 如果需要取值的时候 通过该地址取值
print(res.__next__())   # 1 取值一次给一个
print(res.__next__())   # 2
print(res.__next__())   # 3
print(res.__next__())   # 4
print(res.__next__())   # StopIteration 没有值可以被取

PS:

(1)如果当值被取尽 会报错因为没有值可以被取了

(2)迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身

 

(5)迭代取值的优点:

  (1)优点:

      不依赖索引取值

      只返回一个生成器地址 不占内存空间

  (2)缺点:

      不能取指定的元素

      取值完毕会报错

      只能从前往后取 

     

(5)for循环本质:

基本定义方式:for 变量名 in 可迭代对象

内部本质:

(1)in后面调用__iter__将其后面的参数转换成可迭代对象

(2)调用__next__用来进行取值

(3)内部如果异常 (即值被取尽)会报StopIteration 此时__next__会自动结束循环

例如:

number = [1,2,3,4]
res = number.__iter__() # 变成可迭代对象


print(res)              
print(res.__next__())   
print(res.__next__())   
print(res.__next__())   
print(res.__next__())   


while True:
    try:
        print(res.__next__())
    except StopIteration:       # 匹配出报错的信息 当取值结束的时候会提醒
        print('值已被取尽')
        break
异常解决方法

 

二:生成器

(1)概念:用户自己的定义的迭代器 

 

(2)生成器定义方式:

  (1)包含关键字yield

  (2)调用生成器 但是不会执行生成器代码

例如:

  

def func():
    print('生成器')
    yield                # 生成器定义关键字
res = func()             # 调用生成器 返回地址

 

(3)生成器取值:

取值与迭代器一样:

例如:

def func():
    print('生成器')
    yield                # 生成器定义关键字
res = func()             # 调用生成器 返回地址
res.__next__()          # 生成器

 

(4)生成器返回值

  (1)默认情况下返回None

  ( 2)手工指定返回元组

# PS:返回值为空
def func():
    print('生成器')
    yield        # 不携带值
res = func()
print(res.__next__()) # None

# 携带返回值
def func():
    print('生成器')
    yield 66,88       # 不携带值
res = func()
print(res.__next__()) # (66, 88)

小练习:自定义一个range的生成器

例如:

def func(start,end,step = 1): # 定义range的开头,结尾,步长
    while start < end:
        yield start
        start += step
for i in func(1,10):
    print(i)

 

(5)yield支持为其传参:

例如:

def dog(name):
    print('%s 准备开吃'%name)
    while True:
        food = yield
        print('%s 吃了 %s'%(name,food))

 

(6)yield的特点:

  (1)当函数被调用的时候 其会将函数转换成生成器

  (2)当调用到yield的时候 函数不会被关闭

  (3)有返回值

 

(7)yield 与return的异同:

  (1)相同点:

      都可以返回值 且可以返回多个值

  (2)不同点:

      yield所属的函数当执行到函数的时候可以被多次调用 而retrun会将函数结束

      yield可以接受外部传值

 

(8)生成器表达式:

  例如:

number = (i for i in range(1,10) if i !=4)
res = number
print(res)             # <generator object <genexpr> at 0x00000000020FDFC0>
print(res.__next__())  # 1

PS:

(1)生成器不会主动执行代码

(2)必须通过调用__next__从地址中取值  

      

 

转载于:https://www.cnblogs.com/SR-Program/p/11189790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值