【python3】11.python高阶内容:迭代器和生成器

2022.12.28 迭代器和生成器

11.python高阶内容:迭代器和生成器

11.1 迭代器(literator)

11.1.1 迭代器说明

迭代器指的就是支持迭代的容器。更确切的说,是支持迭代的容器类对象,这里的容器可以是列表、元组等这些 Python 提供的基础容器,也可以是自定义的容器类对象,只要该容器支持迭代即可。

存在的意义:这种需要先保存一个 items 的列表,但当你做机器学习或者数据处理的时候, 如果这个items列表的数据量很大,就会非常占内存。所以生成器的一个重要目的就是避免在内存中记录这样的一个大数据,避免把内存撑爆。

11.1.2 迭代器使用

从技术上讲,在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 __iter__() __next__()

列表、元组、字典和集合都是可迭代的对象。

【实例1】:元组返回一个迭代器,并打印每个值

mytuple = ("apple", "banana", "cherry")
myit = iter(mytuple)

print(next(myit))
print(next(myit))
print(next(myit))
apple
banana
cherry

【实例2】:"字符串"也是可迭代的对象,包含一系列字符

mystr = "banana"
myit = iter(mystr)

print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
print(next(myit))
b
a
n
a
n
a

【实例3】:用for循环迭代

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
1 2 3 4 

11.2 生成器

11.2.1 生成器定义(generator)

在Python中,一边循环一边计算的机制,称为生成器:generator。

11.2.2 为什么要生成器那

我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

11.2.3 创建生成器

  • 方法1】,只要把一个列表生成式的[]改成(),就创建了一个generator
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
  • 方法2】函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator
def need_return(init_value):
    tmp = init_value
    for item in range(300):
        if item == tmp:
            tmp *= 2
            yield item

for i in need_return(10):
    print(i)
10
20
40
80
160

11.2.4 生成器工作原理

  • 成器(generator)能够迭代的关键是它有一个next()方法,通过重复调用next()方法,直到捕获一个异常.:next 两种方式 t.__next__() 或者 next(t)
  • 下次迭代时,代码从yield下一条语句开始执行
  • 关注点:每次停在哪,下次又开始在哪

11.2.5 举例说明

【实例1】

#encoding:UTF-8
def yield_test(n):
    for i in range(n):
        yield call(i)
        print("i=",i)
    print("Done.")

def call(i):
    return i*2

for i in yield_test(5):
    print(i,",")
  • 第一个next: i=0,式子停留在yield call(i),输出0
  • 第二个next: 从print("i=",i)开始执行,输出i=0;执行到yield call(i)停止,此时i=1,输出 2
  • 第五个next:从print("i=",i)开始执行,输出i=3;执行到yield call(i)停止,此时i=4,输出 8
  • 第六个next:从print("i=",i)开始执行,输出i=4;执行完循环i+1超出5了,直接输出Done

【结果】

0 ,
i= 0
2 ,
i= 1
4 ,
i= 2
6 ,
i= 3
8 ,
i= 4
Done.

【实例2】

#encoding:UTF-8
def yield_test(n):
    for i in range(n):
        k=yield call(i)
        print("k=",k)
    print("Done.")

def call(i):
    return("hh:",i)

k = yield_test(5)
next(k)
>>('hh:', 0)
  • 第一个next:执行到yield call(i) 停止;此时i=0;所以输出:(‘hh:’, 0)
next(k)
>>k= None
>>('hh:', 1)
  • 第二个next:从print("k=",k)开始执行,K的赋值操作没有进行,第二次next()的时候从下句开始了,所以k没有值,输出k= None;执行到下个循环的yield call(i) 停止;此时i=1;所以输出:(‘hh:’, 1)
  • 其他的和【实例1】类似

【结果】

('hh:', 0)
k= None
('hh:', 1)
k= None
('hh:', 2)
k= None
('hh:', 3)
k= None
('hh:', 4)
k= None
Done.

11.3 迭代器和生成器异同

寸摘抄,我也还不懂区别

  • 共同点

生成器是一种特殊的迭代器。

  • 不同点

    • a、语法上:

      生成器是通过函数的形式中调用 yield 或()的形式创建的。

      迭代器可以通过 iter() 内置函数创建。

    • b、用法上:

      生成器在调用next()函数或for循环中,所有过程被执行,且返回值。

      迭代器在调用next()函数或for循环中,所有值被返回,没有其他过程或动作。

    • 迭代器是访问容器的一种方式,也就是说容器已经出现。我们是从已有元素拓印出一份副本,只为我们此次迭代使用。而生成器则是,而生成器则是自己生成元素的。也就是前者是从有到有的复制,而后者则是从无到有的生成。
    • 在用法上生成器只需要简单函数写法,配合yield就能实现。而迭代器真正开发中很难使用到。我们可以把生成器看做,python给我们提供的特殊接口实现的迭代器。

参考

https://www.cnblogs.com/liangmingshen/p/9706181.html

你可能感兴趣的:(python学习,python,迭代器)