python~迭代器~生成器~

本文深入探讨了Python中的迭代器与生成器的概念、工作原理及应用实例,包括斐波那契数列的迭代器实现、普通迭代器与生成器的区别、生成器的使用场景与限制,并通过代码示例展示了如何创建并使用这些高级数据结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class Fibs:
    def __init__(self):
        self.a = 0
        self.b = 1
    def next(self):
        self.a, self.b = self.b, self.a+self.b
        return self.a
    def __iter__(self):
        return self

fibs = Fibs()
for f in fibs:
    print f
    if f>500:
        break
print "**********Done!Tada!!**********"

这就是一个简单的斐波那契数列的迭代器。

所谓的迭代器就是具有next()方法的对象,在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用但是迭代器没有值可以返回,就会引发一个stopIteration异常。

相比于列表,迭代器更加通用和优雅。如果有一个函数,可以一个接一个的计算值,那么在使用时就可以是计算一个值时获取一个值,而不是通过列表一次性获取所有值。如果有很多值,列表就会占用太多内存。

class TestIterator:
    value = 0
    def next(self):
        self.value += 1
        if self.value > 10: raise StopIteration
        return self.value
    def __iter__(self):
        return self

ti = TestIterator()
print list(ti)
print "**********Done!Tada!!**********"
上面这段代码使用了异常来停止了迭代。输出结果如下:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
**********Done!Tada!!**********

下面来说说生成器:

任何包含yield的函数称为生成器。来看个栗子:

def flatten(nested):
    for sublist in nested:
        for element in sublist:
            yield element

nested = [[1,2],[3,2],[1]]
print list(flatten(nested))
print "**********Done!Tada!!**********"

输出结果为:

[1, 2, 3, 2, 1]
**********Done!Tada!!**********

生成器函数可以返回多个值。每次产生一个值(yield语句),函数就会停住,停在那里等待被再次唤醒,然后继续从这一点开始运行。

但是上述生成器只能处理两层嵌套,如果要处理任意层的嵌套,则需要用到递归~

def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested

print list(flatten([[1],[[1,2],[1],[[1],2]]]))

print "**********Done!Tada!!**********"

输出结果:

[1, 1, 2, 1, 1, 2]
**********Done!Tada!!**********

代码的理解:当我们试图用for循环展开一个基本元素,比如数字的时候,就会引发typeerror异常,这时候,这个异常就会被except捕捉到,然后直接用yield语句把这个元素返回。

但是如果我们需要展开的是一个数组什么的,for循环就会正常的进行下去,然后检查这个数组的sublist是否还可以展开。如果不可以展开了,那么递归函数就会将sublist返回来,在上层函数中yield~如果可以展开,就会递归下去了blahblah~

但是如果上面的代码改成这样子:

def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested

print list(flatten(['a','b','c']))

print "**********Done!Tada!!**********"

哥们儿你还敢运行一下不~不要怪我木有警告你喔~~

好吧,我告诉你喔,会导致无穷迭代的,因为一个字符串的第一个元素是一个长度为1的字符串,而长度为一的字符串的第一个元素就是字符串本身。

别着急别着急,下面这样写就好了:

def flatten(nested):
    try:
        try: nested+' '
        except TypeError:pass
        else:raise TypeError
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except TypeError:
        yield nested

print list(flatten(['a',['b',['c']]]))

print "**********Done!Tada!!**********"

如果表达式
try: nested+' '

引发了一个TypeError,就会被忽略(表示此时nested不是一个字符串),如果没有引发的话(此时nested是一个字符串),那么就会自己引发一个TypeError异常。

总结一下:生成器是一个包涵yield关键字的函数,当它被调用时,在函数体中的代码不会被执行,而是会返回一个迭代器。每次请求一个值,就会执行生成器中的代码,直到遇到一个yield语句:意味着生成一个值。

ok~就酱紫啦~兔几要去吃果果了~


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值