迭代器以及生成器

一:迭代器:

【1】ide

迭代概念:函数

(1)便是重复的过程spa

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

例如:对象

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

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

 

【2】blog

(1)迭代的做用:索引

  (1)对于字符串 列表 元组能够经过索引取值内存

  (2)字典 集合 文件类型不支持索引取值 能够经过迭代对其进行取值utf-8

 

(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__从地址中取值  

相关文章
相关标签/搜索