对Python中for循环的理解

两个概念

迭代器:实现了__next__()方法的对象,用于对象元素的演进遍历
可迭代对象:实现了__iter__()方法的对象,用于生成该对象对应的迭代器

for循环

到目前为止,您可能已经注意到大多数容器对象都可以使用 for 语句:

for element in [1, 2, 3]:
    print(element)
for element in (1, 2, 3):
    print(element)
for key in {'one':1, 'two':2}:
    print(key)
for char in "123":
    print(char)
for line in open("myfile.txt"):
    print(line, end='')

在这些表达式的背后,for语句会调用容器对象中的__iter__()方法。该方法返回一个实现了__next__()方法的迭代器,该方法将逐一访问容器中的元素。当元素用尽时,__next__()将引发StopIteration异常来通知for循环终止。
所以对于一个for循环,它其实可以等价于:

_iterable = iter(iterable)  # iterable.__iter__()
while True:
    try:
        do_something(next(_iterable))  # _iterable.__next__()
    except StopIteration:
        break

生成器

生成器的外部行为和迭代器很相似,它的创建方法类似于标准的函数,但它的返回语句不是return而是yield,如下是生成器的构建模板

def reverse(data):
    for index in range(len(data)-1, -1, -1):
        yield data[index]

当利用这个函数模板生成一个实例对象后,这个实例对象自动创建__iter__()和__next__()方法。同时这个实例对象不像普通函数那样直接被执行,而是像迭代器那样在调用next时才执行,同时它也会像迭代器那样对自身的演进状态进行保存。,当迭代结束时,它也会自动引发StopIteration。
下面是其使用实例演示

>>> for char in reverse('golf'):
...    print(char)
...    
f
l
o
g

生成器相比于迭代器的好处是它会自动生成__iter__()和__next__()方法,写起来更简洁,省事很多

生成器推导式

某些简单的生成器可以写成简洁的表达式代码,所用语法类似列表推导式,将外层为圆括号而非方括号。 这种表达式被设计用于生成器将立即被外层函数所使用的情况。 生成器表达式相比完整的生成器更紧凑但较不灵活,相比等效的列表推导式则更为节省内存。

>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260

总结

生成器与迭代器的外部特性相同,但是这种外部特性的内部实现方式是完全不同的。Python中的for循环与C中的for循环是完全不一样的,他们的实现机理与外部特性都是完全不同的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值