python读书笔记之迭代器和生成器

可迭代对象

可迭代对象可以使用for循环遍历取值, 比如:列表、元组、字典、集合、range、字符串。

可迭代对象必须实现__iter__()魔法函数

from collections.abc import Iterable

print(isinstance([],Iterable)) # 判断列表是否是可迭代对象
print(isinstance((),Iterable))  # 判断元组
print(isinstance({},Iterable))  # 判断集合
print(isinstance("hello world",Iterable))  #判断字符串
print(isinstance(100,Iterable))

迭代器

迭代器对象,必须要实现__next__()魔法函数。

list、tuple等都是可迭代对象,可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的 iter 方法。next()实际调用了迭代器的__next__()方法

获取字符串的迭代对象

from collections.abc import Iterator
# 将字符串创建迭代器对象
str1 = "hello world"
iter1 = iter(str1)  # 使用iter()函数获取迭代器对象
print(type(str1))  
print(type(iter1))  # type()返回变量的类型

获取列表的迭代对象

# 将list对象创建迭代器
list1 = [1, 2, 3, 4, 5]

iter1 = iter(list1)
print(next(iter1))  # 输出1
print(iter1.__next__())  # 和上一行效果相同, 输出2

for i in iter1:
     print(i)
print(isinstance(iter1,Iterator))  # 判断是否是迭代器类型

# 将tuple对象创建迭代器
tuple1 = (1, 2, 3, 4, 5)
iter3 = iter(list1)

#使用for循环遍历迭代器
for i in iter3:
     print(i)

# 利用next遍历迭代对象
while True:
     try:
         print(next(iter1))
     except StopIteration:
         break

自定义可迭代对象

# 定义可迭代对象
class TestIterable:
    def __init__(self,x):
        self.x = x

    def __iter__(self):  # 可迭代对象必须实现此方法
        return iter(self.x) # 返回x属性的可迭代对象

# 这里的a就是可迭代对象
a = TestIterable('123')

# for循环输出1   2    3
for x in a:
    print(x)

next(a)  # 这里不能调用next(a)方法,因为没有定义

自定义可迭代器

class TestIterator:
    def __init__(self,x):
        self.x = x  # 获取传入的对象
        self.index = 0  # 维护索引值

    def __next__(self):  # 迭代器必须实现此方法
        try:
            result = self.x[self.index] # 获取传入对象的值
        except IndexError:
            raise StopIteration  # 如果索引值错误,抛出停止迭代
        self.index += 1  # 索引值+1,用来获取传入对象的下一个值
        return result    # 返回传入对象的值

	# 实现此方法才能用于for循环,迭代器可以没有此方法
    def __iter__(self):
        return iter(self.x)

a = TestIterator([1, 2, 3])
print(next(a))
print(next(a))

for x in a:
    print(x)

自定义迭代器,实现自己的迭代逻辑

class Sequence(object):
    def __init__(self):
        self.num = 2

    def __iter__(self):
        return self

    def __next__(self):  # 自己的迭代逻辑,这个迭代器产生小于10的偶数序列
        val = self.num
        if val>=10:
            raise StopIteration
        self.num += 2
        return val


test_object = Sequence() # test_object即是一个迭代器对象
print(next(test_object))
print(next(test_object))
for i in test_object:
    print(i)

为什么要使用迭代器

使用迭代器可以节省空间,举个例子,如果一个很大的列表,如果只需要取前十个数据,直接使用for 循环会把列表全部读到内存中,但是如果使用迭代器则只会一次读一个。

生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

使用生成器的两种方式

  • 第一种:只要把一个列表生成式的[]改成(),就创建了一个generator
  • 第二种:如果一个函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。调用函数就是创建了一个生成器(generator)对象。

第一种生成器使用方式

L = [x * x for x in range(10)]
print(type(L))  # L是一个list类型,<class 'list'>
G = (x * x for x in range(10))
print(type(G))  # G是生成器,<class 'generator'>

print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print(G) # <generator object <genexpr> at 0x130658d60>

print(next(G))  # 既可以使用next()函数也可以使用for循环获取生成器的值
print(next(G))
print(next(G))

for i in G:
    print(i)

第二种生成器使用方式
带有 yield 的函数不再是一个普通函数,而是一个生成器generator。
yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

def yield_test(n):
    for i in range(n):
        print('i,',i)
        yield i*2
        print("i=",i)  # 下次迭代时从这条语句开始
    print("Done.")

for i in yield_test(3):
    print(i)

"""
第一次迭代:i = 0

i,0
0

第二次迭代: i = 1
i=0,
i,1
2

第三次迭代: i = 2
i= 1
i, 2
4
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值