美文网首页
关于python的可迭代对象、迭代器、生成器的理解

关于python的可迭代对象、迭代器、生成器的理解

作者: Hmcf | 来源:发表于2019-10-30 15:54 被阅读0次

最近有朋友问到python中的迭代器和生成器的区别和作用,以及如何定义和区分,今天在这里稍微总结一下。

可迭代对象

定义:可迭代对象必须实现 "_iter_()" 方法。
python中的字符串、列表、元组、字典、集合、文件对象等都是可迭代对象。

口说无凭,上bug...不对,上法器:可使用内建函数 isinstance 来判别。

from collections import deque
from collections.abc import Iterable, Iterator

s = "hello hmcf"
print("string is iterable? ", isinstance(s, Iterable))
print("string is iterator? ", isinstance(s, Iterator))

l = [1, 2, 3, 4]
print("list is iterable? ", isinstance(l, Iterable))
print("list is iterator? ", isinstance(l, Iterator))

d = {"city": "hangzhou", "age": 26}
print("dict is iterable? ", isinstance(d, Iterable))
print("dict is iterator? ", isinstance(d, Iterator))

t = (1, "a", 2.3, [5, 6])
print("tuple is iterable? ", isinstance(t, Iterable))
print("tuple is iterator? ", isinstance(t, Iterator))

de = deque("abcdefg")
print("deque is iterable?", isinstance(de, Iterable))
print("deque is iterator?", isinstance(de, Iterator))

结果如下:

string is iterable? True
string is iterator? False
list is iterable? True
list is iterator? False
dict is iterable? True
dict is iterator? False
tuple is iterable? True
tuple is iterator? False
deque is iterable? True
deque is iterator? False

可使用 dir() 函数来打印出来看看对象有没有_iter_方法,也可以查看 builtins.pyi 源文件找到对应方法中的定义。

迭代器

迭代器是在可迭代对象的基础上创建的访问集合元素的一种方式。

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,并且只会迭代一遍。

迭代器对象必须同时实现 "_iter_()" 和 "_next_()" 方法才是迭代器。对于迭代器来说,"_iter_" 返回的是它自身 self,"_next_" 则是返回迭代器中的下一个值,最后没有元素时。

字符串,列表或元组对象都可用于创建迭代器。迭代器是可迭代对象,但可迭代对象不一定是迭代器。
迭代器的优点:每次只从对象中读取一条数据,不会造成内存的过大开销。

至于迭代器的判断方式,在上面的可迭代对象中已经体现了。

for循环机制

为什么需要for循环机制?因为需要去触发、调用迭代器。字符串 、字典、列表在for循环的作用下,会生成迭代器,然后被使用。

x = 'hello'
for i in x:                    #iter_x=x.__iter__()
    print(i)                   #iter_x.__next__()
iter_l =x.__iter__()           #遵循迭代器协议,生成可迭代对象
print(iter_l.__next__())       #for循环和索引没关系 基于迭代器机制
  • 当对象本身就是迭代器时,For循环工作机制:

调用 _iter_方法,返回自身self,也就是返回迭代器。不断地调用迭代器的next()方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration

  • 在可迭代对象中,for循环工作机制:

先判断对象是否为可迭代对象(等价于判断有没有_iter_方法),没有的话直接报错,抛出TypeError异常。有的话,调用 _iter_方法,返回一个迭代器。在python内部不断地调用迭代器的_next_方法,每次按序返回迭代器中的一个值。迭代到最后没有元素时,就抛出异常 StopIteration,这个异常 python 自己会处理,不会暴露给开发者。

生成器

定义:边循环边计算的机制就称为生成器(generator)(对象里面不是具体的内容,而是一个产生数据的算法)

生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用,但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小,而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数,但是表现得却像是迭代器。

python中生成器是迭代器的一种,可以被用作控制循环的迭代行为。

它有两种形式:

  • 生成器函数
    使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()
  • 生成器表达式
    只要把一个列表生成式的[]中括号改为()小括号,就创建一个生成器。可以直接调用next()方法依次取出内容(取到最后会爆出错误,不优雅),另外的就是可以使用for循环来调用。
generator = (x for x in [1,4,6,7,9] if x<5)
for n in generator:
    print(n)

相关文章

  • Python基础-16生成器-迭代器

    16.生成器-迭代器     可循环迭代的对象称为可迭代对象,迭代器和生成器函数是可迭代对象,在Python中提供...

  • 理解迭代器/生成器

    完全理解Python 迭代对象、迭代器、生成器 迭代和生成操作总结 Python迭代器 http://www.ji...

  • Python中的迭代器和生成器

    今天我们来学习下Python中的迭代器和生成器。 迭代和可迭代对象 在学习迭代器之前,我们需要了解下迭代和可迭代对...

  • 理解Python中的yield以及协程

    要理解yield,必须先清楚可迭代对象、迭代器和生成器的概念。 一、可迭代对象 大部分对象都是可迭代,只要实现了_...

  • 迭代器、生成器和协程

    迭代器、生成器和协程 可迭代(Iterable) Python 中任意的对象, 只要定义了可以返回一个迭代器的 _...

  • 生成器(Generators)

    生成器(Generators) 首先要理解迭代器(iterators) 可迭代对象(Iterable):Pytho...

  • 可迭代对象、迭代器、生成器

    可迭代对象 --> 迭代器 --> 生成器; 可迭代对象:实现了__iter__()方法的对象,该方法返回迭代对象...

  • Python可迭代对象,迭代器,生成器关系

    列表,元组,字符串,迭代器,生成器都是可迭代对象。所以,可迭代对象不一定是迭代器,生成器。 将一个可迭代对象传递给...

  • 迭代器

    可迭代对象(Iterable): for迭代器(Iterator): for + next生成器属于迭代器。 验...

  • yield and Iterator

    Generator(生成器) 生成器是特殊的迭代器,迭代器不一定是生成器。 生成器与迭代器均是可迭代对象。 目前学...

网友评论

      本文标题:关于python的可迭代对象、迭代器、生成器的理解

      本文链接:https://www.haomeiwen.com/subject/vwvovctx.html