Python Generator初探(一)

本文是作者对Python Generator的初步探索,介绍了迭代器的概念、可迭代对象的定义以及列表推导的使用方式。文章通过实例解释了如何创建自定义迭代器,并强调了列表推导式的简洁性。最后,作者分享了初次写作博客的体验,认为这一过程有助于巩固和理解知识。

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

  • 前言
  • 迭代器(Iterator)
    • 概念
    • 可迭代对象
    • 列表推导
  • 总结

前言

自从一年前接触到Python以来,我就被它的简洁、优雅与强大深深吸引。其中Generator是我最喜爱的特性之一。一直想深入的理解Generator的用法,但是苦于一直被项目压着。最近有时间,我查看了很多资料,算是小有收获。希望能通过这几篇文章来记录自己的收获,当然如果对一些博友有所帮助那是再好不过。鉴于本人水平有限,如有错误,欢迎拍砖。这是我第一次写博客,写的不好的地方也敬请大家谅解!

迭代器(Iterator)

概念

在Python中,要对一个序列进行遍历,最简洁的方式就是使用for … in了:

l = [1,2,3,4]
for item in l:
    print item

不同于C/C++和Java之类的基于计数的遍历:

int a[] = {1,2,3,4]
for (int i = 0; i < 4; i++)
{
    printf("%d\n", a[i]);
}

Python的抽象程度更高,因为原则上它可以用在一切可迭代对象上。

可迭代对象

上面提到了一个术语,可迭代对象。那么什么是可迭代对象呢?下面我模拟了类似内建list的类:

class MyIterator(object):
    def __init__(self, list_entity):
        self.count = -1
        self.list_entity = list_entity

    def next(self):
        self.count += 1
        if self.count == len(self.list_entity):
            raise StopIteration
        return self.list_entity[self.count]

class MyList(list):
    def __init__(self, *args):
        super(MyList, self).__init__(args)

    def __iter__(self):
        return MyIterator(self)

for item in MyList(1,2,3,4):
    print item

简而言之,可迭代对象就是一个定义了_iter_(或者称为迭代起协议)函数的对象,这个函数返回一个定义了next方法的对象。在for…in中使用的时候,Python先以待遍历对象为参数调用iter(其实就是调用待遍历对象的iter函数),这个函数返回一个迭代器,然后一直调用这个迭代器的next方法,直到发生StopIteration异常,退出for循环。严格来说,定义_iter_的对象是可迭代对象,_iter_返回的对象才是迭代器。接着上面的代码,我们可以这么写:

iterator = iter(MyList(1,2,3,4)) #返回一个迭代器
print(iterator.next())          #输出1
print(iterator.next())          #输出2
print(iterator.next())          #输出3
print(iterator.next())          #输出4
iterator.next()                 #产生StopIterator异常

通常情况下,我们不用定义两个类,可以在一个类中同时定义_iter_next函数,例如:

class MyList(list):
    def __init__(self, *args):
        super(MyList, self).__init__(args)
        self.count = -1

    def __iter__(self):
        return self

    def next(self):
        self.count += 1
        if self.count == len(self):
            raise StopIteration
        return self[self.count]

for item in MyList(1,2,3,4):
    print item

这样更简洁!

列表推导

像上面那样写一个迭代器需要一定的工作量,Python中提供了一个更加简洁的方法:列表推导式。
一个简单的列表推导式如下:

a = [x for x in range(7)]

这个列表推导式生成了一个列表[0,1,2,3,4]。
这句代码就相当于:

a = []
for x in range(7):
    a.append(x)

其中for可以嵌套:

a = [(x, y) for x in range(2) for y in range(3)]

这段代码就相当于:

a = []
for x in range(2):
    for y in range(3):
        a.append((x,y))

当然可以添加条件:

a = [x for x in range(10) if x % 2 == 0]
总结

第一次写blog发现,blog真的不好写,感觉自己懂某些概念了,但是写出来还是很困难的。从另一方面说,写blog确实能让自己重新审视自己。校验自己对某些知识点的掌握程度。不管怎样,第一次写blog,受益匪浅,以后有时间多多总结,多多梳理。这篇写得不好的地方,敬请谅解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值