深入理解python中的迭代器和生成器

SEQ19 深入理解迭代器和生成器

1 四个概念区分:容器、可迭代对象、迭代器、生成器;

​ a.“容器”:直观感受就是多个’类似’数据结构的元素组在一起单元,比如,数组、元组、字典都是容器。所有的容器都是可迭代的。
​ b.“可迭代对象(interable)”:Python中一切皆对象。所以Python中只要是可迭代(类似使用for in obj:)的对象,都是可迭代对象。
​ 比如:容器就是可迭代对象;“迭代”:不等于简单的重复。迭代包含了有规律的变化
​ c.“迭代器(interator)”:“可迭代对象” 不等于"迭代器","可迭代对象"通过iter()函数可以得到一个迭代器,迭代器通过next()得到
​ 下一个元素。
​ PS:首先要明一点,迭代器是一个类(class),比如:class list,class set,class str 都是class
​ d.“生成器(generator)”:是一种特特类型的迭代器,但反之不成立(即迭代不一定是生成器)。当生成器所有元素都遍历完后,会抛出StopIteration异常。

在这里插入图片描述

2 如何判断对象是否可迭代?

​ a. iter()函数,如果可迭代,则返回一个可迭代对象,否则报错;
​ b. from collections import Iterable
​ instance(v, type)

#code 1
from collections import Iterable
params = [1234, '1234', [1, 2, 3, 4], set([1, 2, 3, 4]), {1:1, 2:2, 3:3, 4:4}, (1, 2, 3, 4)]
for i in params:
    tag = isinstance(i, Iterable)
    print(f"对象:{i} 是否可迭代:{tag}:")

3 如何构建一个可迭代对象?

1)使用[]

# code 2
from collections import Iterable
a = [i for i in range(1001)]
print(isinstance(a, Iterable))

2)实例化一个迭代器,得到一个可迭代对象

# code 3
# BookCollections()  是个迭代器
books = BookCollections()

4 迭代器(Iterator)

1) 迭代器–如何构建一个迭代器?

迭代器的本质:迭代器是个类,迭代器是个类,迭代器是个类~~~重要事情说三遍!
需要在类中实现__iter__()和__next__() 方法,就构建了一个迭代器。

# code 4
class BookCollections(object):
    def __init__(self):
        self.data = ["《往事》", "《只能》", "《回味》"]
        self.cur = 0
    def __iter__(self):
        return self

    def __next__(self):
        if self.cur > len(self.data):
            raise StopIteration()
        r = self.data[self.cur]
        self.cur += 1
        return r
from collections import Iterable
books = BookCollections()
print(f'books的类型{isinstance(books,Iterable)}')
print(f'BookCollections()的类型{isinstance(BookCollections(), Iterable)}')

2) 迭代器–迭代器的“一次性”

迭代器具有“一次性”的特性,即只能遍历一次。因为生成器也是一种懒人版本的迭代器,所以也有“一次性“的特性。

# code 5
books = BookCollections()
for book in books:
    print(book)
for book in books:
    print(book)
#如上第二个for循环不会打印任何

若需要多次遍历,需要:

​ a.复位重新生成一个可迭代对象;

# code 6
book1 = BookCollections()
books = BookCollections()

​ b.使用copy.copy()或者copy.deepcopy()

books = BookCollections()
import copy
books_copy = copy.copy(books)
for book in books:
    print(book)
for book in books_copy:
    print(book)

5 生成器(generator)

生成器的本质:是一种函数,一种算法,边执行,边“生成”。如

生成器,可以理解为“懒人版本的迭代器”。

1) 如何声明一个生成器

Python中用小括号括起来即表示生命一个“生成器”,如(i for i in range(1001))

a = (i for i in range(1001))
print(type(a))
-----------------
<class 'generator'>

2)一个对比实例

需求

获取0~10000之间的每个数的和

方案

方案1:常规方案:列表 + 循环

n = [i for i in range(10001)]
sum = 0
for i in n:
    sum += i
print(sum)

方案2:生成器方案

def gen(max):
    n = 0
    while n <= max:
        yield n
        n += 1
sum = 0
for i in gen(10000):
    sum += i
print(sum)
优劣对比

方案一中,n是直接保存在内存中的一个类别,占用很多内存,如果数据多到超过服务器内存时,会出现OOM的异常。

方案二种,生成器保存的实际上是一种算法,每次返回yield出的值,所以不会占用太大的内存。

3) return和yield关键字

return:在程序函数中返回某个值,返回之后函数不在继续执行,彻底结束。
yield:带有yield关键字的函数是一个迭代器,函数遇到yield关键字,则返回yield后的值后,然后跳到next()函数从yield处继续执行,直到程序结束。


def gen(max):
    n = 0
    while n <= max:
        yield n
        n += 1
#########################
for i in gen(5):
    print(i)
# 等价于
g =gen(5)
i = 1
while i <= 6:
    i += 1
    print(next(g))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值