# -*- coding: utf-8 -*-import requests
from collections import Iterable, Iterator
classWeatherIterator(Iterator):# 定义迭代器 def__init__(self, cities):
self.cities = cities
self.index =0defget_weather(self,city):# 获取天气的数据
r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city='+ city)
data = r.json()['data']['forecast'][0]return'%s:%s,%s'%(city, data['low'], data['high'])defnext(self):# 定义迭代器的next()方法if self.index ==len(self.cities):raise StopIteration # 如果全部迭代完的处理方法
city = self.cities[self.index]
self.index +=1return self.get_weather(city)classWeatherIterable(Iterable):# 定义可迭代对象def__init__(self, cities):print' __init__'
self.cities = cities
def__iter__(self):print'__iter__'return WeatherIterator(self.cities)# 返回一个迭代器对象if __name__ =='__main__':# for x in obj 循环的基本原理是,# obj是一个可迭代对象,for循环之前,先调用obj.__iter__方法,返回一个迭代器对象Iterator,迭代器对象通过nex()t方法,返回每个值# 要写出自己的可迭代对象,需要继承Iterable,__iter__()方法,并返回一个可迭代器对象# 在自己的迭代器对象中定义next()方法,通过next方法,获取每次迭代的值
city_list =[u'深圳',u'北京',u'上海',u'广州',u'青岛',u'荆州',u'武汉']for x in WeatherIterable(city_list):print x
二、使用生成器函数实现可迭代对象
classPrimeNumber(object):def__init__(self, start, end):
self.start = start
self.end = end
defget_prime(self, k):# 判断是否是素数,如果是,返回Trueif k <2:returnFalsefor x inxrange(2, k):if k % x ==0:returnFalsereturnTruedef__iter__(self):# for...in..循环时,先调用__iter__,返回一个迭代生成器对象print'__iter__'for x inxrange(self.start, self.end):if self.get_prime(x):# yield是一个关键词,类似return, 不同之处在于,yield返回的是一个生成器对象,生成器每次调用next,返回一个xyield x
for x in PrimeNumber(0,100):print x
三、如何进行反向迭代及如何实现反向迭代
classFloatRange(object):def__init__(self, start, end, step=0.5):
self.start = start
self.end = end
self.step = step
def__iter__(self):# 定义正向迭代方法
t = self.start
while t <= self.end:yield t
t += self.step
def__reversed__(self):# 定义反向迭代方法
t = self.end
while t >= self.start:yield t
t -= self.step
for x in FloatRange(1,4,0.5):# 默认调用__iter__()print x," ",for x inreversed(FloatRange(1,4,0.5)):# 调用__reversed__()方法,进行反迭代print x," ",
四、对迭代器做切片操作
from itertools import islice
# islice切片对象,可以对可迭代对象进行切片# islice(iterable, [start,] stop [, step]) --> islice object # 如果只有一个参数,表示从第一个开始第一个元素开始,如果想从某一个位置到最后,可以islice(iterable,40,None)方法
f=open('digital','r')for x in islice(f,3,5,1):print x,
五、在for中迭代多个可迭代对象
from random import randint
from itertools import chain
# 要求统计三科总成绩
chinese =[randint(60,100)for _ inxrange(40)]
math =[randint(60,100)for _ inxrange(40)]
english =[randint(60,100)for _ inxrange(40)]
total =[]# 总分列表for c, m, e inzip(chinese, math, english):# zip将三个可迭代对象合并成一个元组列表[(),()...],如果三个对象长度不同,以最小的为准
total.append(c + m + e)print total
# 要求统三个班90分以上人数
c1 =[randint(60,100)for _ inxrange(40)]
c2 =[randint(60,100)for _ inxrange(45)]
c3 =[randint(60,100)for _ inxrange(32)]
total =0for x in chain(c1, c2, c3):# chain 将多个可迭代对象串联成一个可迭代对象if x >90:
total +=1