Python168的学习笔记2

关于for循环,其实质是利用被循环对象的__iter__,或者__getitem__属性接口,由可迭代对象得到迭代器。for循环就是不断调用.next(),直到最终捕获到stop。

 

 1 import requests
 2 from collections import Iterable,Iterator
 3 
 4 class WeatherIterator(Iterator):#可迭代对象
 5     def __init__(self,cities):
 6         self.cities = cities
 7         self.index = 0
 8 
 9     def getweather(self,city):
10         r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city='+city)#这是一个免费的天气api
11         data = r.json()['data']['forecast'][0]
12         return '%s:%s,%s'%(city,data['low'],data['high'])
13     
14     def next(self):
15         if self.index == len(self.cities):
16             raise StopIteration
17         city = self.cities[self.index]
18         self.index += 1
19         return self.getweather(city)
20     
21 class WeatherIterable(Iterable):#迭代器对象
22     def __init__(self,cities):
23         self.cities = cities
24         
25     def __iter__(self):#迭代器接口
26         return WeatherIterator(self.cities)
27     
28 for x in WeatherIterable([u'北京',u'上海',u'广州',u'长春']):
29     print x

先是利用内置的iterator创建一个新的包含next的可迭代对象,然后再创建一个迭代器(这个迭代器调用了可迭代对象)。调用的时候直接使用迭代器(使用其__iter__的接口)就可以了,而且达到一个用时访问的功能。

 1 #coding:utf-8
 2 class PrimeNumbers(object):
 3     def __init__(self,start,end):
 4         self.end = end
 5         self.start = start
 6     
 7     def  isPrimeNumber(self,k):
 8         if k<2 :
 9             return False
10         for i in xrange(2,k):
11             if k%i == 0:
12                 return False 
13         return True
14     
15     def __iter__(self):#迭代接口
16         for k in xrange(self.start,self.end+1):
17             if self.isPrimeNumber(k):
18                 yield k #利用生成器对象来完成迭代
19                 
20 for i in PrimeNumbers(1,20):
21     print i

利用yield生成器来实现__iter__(可迭代),因为yield的本质可以说是return 和 next的合体(暂时这样理解)

 

对list的反序操作,就是list.reverse(),可以得到反序的list,但是这样就是对list进行了操作,原有的顺序改变了。

而list[::-1],是产生一个新的,反序的list,可能会浪费内存。

所以最好的方法是,去实现list.__reversed__的方法。(正向迭代,就是实现__iter__;反向迭代,就是实现__reversed__)。

 

使用itertools.islice可以对迭代器进行切片操作,islice(iter,[start,]end[,step]),不过对迭代对象进行切片操作后,迭代对象的指针会停留在切片的停止的地方,所以如果想要再次用,需要重新申请迭代对象。

 

关于处理多个迭代对象,并行(同时迭代),用zip函数,zip(*seq),会返回最短那个迭代对象长度的,由每个迭代对象各个元素组成的子tuple组成的list(ps:用itertools.izip()可以返回iter);串行(一个接着一个),用itertools.chain,chain(*iter),直接将所有迭代对象接起来。

注意,所有for对iter的操作,都会使iter的指针去到结尾,需要重新申请迭代对象才能使用。(也就是重新做一个迭代器,或者说在第一次使用时将迭代器list化)

总的来说,迭代器就只能用一次。然后针对不同的迭代对象,有不同的重置方法,如file操作中的fetch()。

posted @ 2016-11-04 15:26  Nanrou  阅读(242)  评论(0编辑  收藏  举报