- 前言
- 迭代器(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,受益匪浅,以后有时间多多总结,多多梳理。这篇写得不好的地方,敬请谅解!