Python之迭代器、生成器

1 迭代器
        迭代器是Python中用于遍历可迭代对象(如列表、字符串、元组等)的机制。它通过提供__next()__方法,依次访问可迭代对象中的各个元素,直到元素被遍历完毕为止。

        当一个对象实现了迭代器协议时,它就成为一个迭代器对象。迭代器对象可以使用Python的for循环进行遍历。在每一次循环中,for循环会调用迭代器对象的__next()__方法,返回当前元素的值。一旦所有元素都被遍历过,迭代器对象就会抛出StopIteration异常,表示迭代结束。

        Python中的迭代器实现了两个方法:__iter() __和 __next()__。__iter()__方法返回迭代器对象本身,而__next()__方法返回迭代器对象的下一个元素,直到所有元素都被遍历完毕。

以下是一个简单的迭代器示例:

class MyIterator:
    def __init__(self, my_list):
        self.my_list = my_list
        self.index = 0
    def __iter__(self):
        return self
    def __next__(self):
        if self.index >= len(self.my_list):
            raise StopIteration
        result = self.my_list[self.index]
        self.index += 1
        return result
 
my_list = [1, 2, 3, 4, 5]
my_iterator = MyIterator(my_list)
 
for item in my_iterator:
    print(item)
 
 

这个迭代器将会输出下列结果

1
2
3
4
5
可以看到,在每次for循环中,迭代器对象的next()方法被调用,返回当前元素,直到所有元素都被遍历完毕。

迭代器取值与索引取值的区别:

迭代取值
    1. 不依赖于索引取值的一种取值方式
    2. 不能够重复取值,只能够从左往右固定取值
索引取值
    1. 它能够重复取值(通过索引 L[0])
    2. 它需要是容器类型

2 生成器
2.1 引入
        通过列表生成式,我们可以直接创建一个列表,但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

  所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间,在Python中,这种一边循环一边计算的机制,称为生成器:generator, python中生成器是自定义迭代器的一种。

        Python生成器是一种特殊类型的函数,它能够按需生成一个数据序列,而不是一次性生成整个序列。相比于使用列表等序列容器来存储全部元素,使用生成器能够在节省内存的同时,提高代码执行效率。

Python生成器的特点包括:

使用yield语句来返回数据并暂停函数的执行,下次调用函数会从yield语句断点处继续执行。

生成器函数执行过程中,可以通过yield语句接收来自调用方的数据,即实现了双向通信。

生成器可以使用for循环等方式进行遍历,也可以使用next()函数手动获取下一个元素。

示例代码:

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        yield a
        a, b = b, a + b
        
# 使用for循环遍历生成器
for i in fibonacci(10):
    print(i)
    
# 手动获取生成器中的下一个元素
fib = fibonacci(5)
print(next(fib))
print(next(fib))
print(next(fib))

2.2  关键字yield

        当函数中一旦出现了yield关键字,函数在没有被调用的时候仍然是普通函数,但是只要一调用函数,那么,该函数就不是普通函数了,就变成了生成器。

def index():
 
    print('from index')
    print('from index')
 
    yield 123,234,345 # 停住程序,以元组的方式返回
 
    print('second')
    print('second')
    yield 'hello'
    print('three')
    yield
 
res=index()  # res.__iter__()
print(res)  

2.3 yield和return的对比

yield
    1. 代码遇到yield不会停止,而是停住
    2. yield也可以有返回值,并且还支持多个,以元组的形式返回
    3. yield可以把一个函数变成生成器,next取值
    

return
    1. 代码遇到return就会停止
    2. return可以有返回值并且还支持多个,以元组的形式返回

2.4 生成器yield的其他用法

生成器其实就是一个自定义的迭代器

res.__next__() # 只要你调用next方法,代码就会走到函数中第一个yield关键字所在的位置停住
res.__next__() # 代码从上一次yield停住的地方继续往下执行,走到遇到下一个yield停住

def eater(name):
    print('%s:正在吃...' % name)
    while True:
        food = yield
        print('%s正在吃%s' % (name, food))
 
'''eater就变成了生成器'''
res=eater('jerry') # 生成器对象:generator object
print(res) # <generator object eater at 0x0000021869489B30>
 
res.__next__()
# res.__next__()
 
# send做了两件事情:1. 传值给yield、2. 执行__next__
res.send('包子')
res.send('水果')
res.send('水果')
res.send('水果')

3 生成器表达式
列表生成式
res = [name for name in names_list]
print(res) # 就是一个列表
 
res1 = (name for name in names_list)
print(res1)
names_list = ['kevin', 'jerry', 'tony', 'oscar']
res1 = (name for name in names_list)
print(res1) # <generator object <genexpr> at 0x00000218F4569CF0>
 
print(res1.__next__())
print(res1.__next__())
print(res1.__next__())
print(res1.__next__())
 
"""生成器表达式如果不使用数据,就不给你数据"""
 
把迭代器、生成器看成是一个工厂,什么时候需要数据工厂就给你加工数据
目的:就是为了节省内存空间

3.1生成器笔试题 
 
# 求和
def add(n, i):
    return n + i
# 调用之前是函数 调用之后是生成器
def test():
    for i in range(4):
        yield i
g = test()  # 初始化生成器对象
for n in [1, 10]:
    g = (add(n, i) for i in g)
 
res = list(g)
print(res)
 
#A. res=[10,11,12,13]
#B. res=[11,12,13,14]
C. res=[20,21,22,23]
#D. res=[21,22,23,24]

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Python中的生成器是一种基于惰性计算的概念,它们可以有效地处理大量的数据或者无限序列。下面我将分别介绍生成器(Iterator)是一个实现了代协议(Iterator Protocol)的对象。通过调用内置函数 `iter()` 可以将可代对象转换为对象可以使用内置函数 `next()` 来逐个访问数据元素,直到没有更多的元素可供访问时,会引发 `StopIteration` 异常。例如,可以使用来遍历列表、元组、集合等容类型的数据。 生成器(Generator)则是一种特殊的。它不需要显式地实现代协议,而是通过函数中的 `yield` 关键字来实现惰性计算。生成器函数在每次调用时返回一个值,并在下一次调用时从上一次离开的位置继续执行。这样可以节省大量的内存空间,并且提高程序的效率。生成器函数定义时使用 `def` 关键字,并包含至少一个 `yield` 关键字。 下面是一个简单的示例代码,演示了如何使用生成器: ```python # 使用遍历列表 my_list = [1, 2, 3, 4, 5] my_iter = iter(my_list) while True: try: item = next(my_iter) print(item) except StopIteration: break # 使用生成器生成斐波那契数列 def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b fib = fibonacci() for i in range(10): print(next(fib)) ``` 希望以上解释能够帮助你理解生成器的概念。如果有任何进一步的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值