迭代器

Posted blue-tea

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了迭代器相关的知识,希望对你有一定的参考价值。

1.迭代器

(1).迭代器的相关介绍

什么是迭代器?

  迭代:指一个重复的过程,每次的迭代都必须基于上一次的结果。’

  迭代器:迭代取值的工具。

为什么要用?

  迭代器给你提供了一种不依赖于索引取值的方式。

  需要迭代器的数据类型有:字符串,列表,元组,字典,集合。

# 重复+每次迭代都是基于上一次的结果而来的
s = ‘hello‘
n = 0
while n < len(s):
    print(s[n])
    n +=1
>>>:输出结果跟 for i in s\n  print(i)  一致

(2).可迭代对象

  只要内置有__iter__方法的都叫做可迭代对象。针对双下划线开头双下划线结尾的方法,推荐读法为  双下+方法名。

  基本数据类型中是可迭代对象的又:字符串,列表,字典,元组,集合。

  文件对象(执行内置的__iter__之后还是本身,没有任何变化):文件对象本身就是迭代器对象。

res = l.__iter__()    # res = iter(l)

可迭代对象执行内置的--iter--方法得到的就是该对象的迭代器对象。 

2.迭代器取值

  (1).内置有__inter__方法

  (2).迭代器取值一定要用__next__方法

补充:迭代器一定是可迭代对象,而可迭代对象不一定是迭代器对象。

d = [1,2,3,4]
iter_d = d.__iter__()   #将可迭代器对象d装换成迭代器对象
print(iter.__next__())    #迭代器取值 ,调用
print(iter.__next__())     # 一行只能取一个值
print(iter.__next__())     #如果取完了以后再取,直接报错StopIteration
f1 = open(fxxx.txt,r,encoding=utf-8) #调用f1内置的__iter__方法
iter_f = f1.__iter__()
print(iter_f is f1)
#迭代器对象无论执行多少次__iter__方法,得到的都还是迭代器对象本身
print(f1 is f1.__iter__().__iter__().__iter__().__iter__())

迭代器取值的特点:只能完后依次取,不能后退

3.for循环的本质

d = name:li,password:123,hobby:read
print i in d:
    print(i)
# for循环后面的in关键词,跟的是一个可迭代对象for

for循环内部的本质:

  (1).将in后面的对象调用__iter__转换成迭代器对象。

  (2).调用__next__迭代取值。

  (3).内部有异常捕获topIteration,当__next__报出这个错误,循环自动结束循环

可迭代对象:内置有__iter__方法的。

迭代器对象:既内置有__iter__也内置有__next__方法

迭代取值的优缺点

  优点:不依赖于索引值,内存中永远只占一份空间,不会导致内存溢出。

  缺点:不能够获取指定的元素,取完之后会报StopIteration错。

4.生成器

生成器:常指用户自己所定义的迭代器。所有的生成器都是迭代器,因为生成器对象有 __iter__ 和 __next__ 方法,且 __iter__ 方法返回自身

def func():
    print(first)
    yield  666  # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
     print(second)
     yield  777
#yield后面跟的值就是调用迭代器__next__方法你能得到的值
#yield既可以返回一个值也可以返回多个值,并且多个值也是按照元组的形式返回
g = func()  # 生成器初始化:将函数变成迭代器
print(g)  #>>>:<generator object func at 0x00000214D9AFCF10>生成器对象func位于这个地址内
print(g.__next__())
print(g.__next__())

补充:生成器不会主动执行任何一行代码,必须要通过__next__才能触发代码运行。

5.yield的用法

  yield支持外界为其传参,并且能提供一种自定义生成器方式,可以将函数的运行状态给暂停住,有返回值。

def func(name):
    print(%s 准备开吃)
    while True:
        food = yield    #当函数内有yield关键字的时候,调用该函数不会执行函数体代码
        print(%s 吃了 %s%(name,food))
g = func(li)    #将函数变成来生成器
g.__next__()    #必须先将代码运行至yield才能够为其传值
g.send(饺子)    # 给yield左边的变量传参,相当于触发了__next__方法

与return的异同之处

  相同点:都可以返回值,并且都可以返回多个

  不同点:yield可以返回多次值,而retrun只能返回一次就立即结束;yield可以接受外部传入的值。

 

以上是关于迭代器的主要内容,如果未能解决你的问题,请参考以下文章

五 迭代器生成器

STL迭代器相关的输出迭代器

课时10:迭代器迭代器失效分析

C++迭代器 iterator

C++迭代器 iterator

25Python之迭代器