python迭代-可迭代对象与迭代器对象

可迭代对象与迭代器对象

问题举例

某软件要求,从网络抓取各个城市的气温信息,并依次显示:

北京:15~22

上海:18~23

......

如果一次抓取所有城市气温信息再显示,显示第一个城市的气温时会由很长的延时,

并且浪费存储空间,我们期望以“用时访问”的策略,并且把所有城市的气温信息封装

到一个对象里,可用for语句进行迭代。

for循环工作流程

来个栗子

list1 = [1, 2, 3, 4, 5]
for ele in list1:
    print(ele)

it = iter(list1)
next(it)
next(it)
next(it)
next(it)
next(it)
next(it)

for循环中in后面的对象一定为可迭代对象

iter()返回一个可迭代器对象,由可迭代对象生成

next()方法对迭代器对象进行迭代

最后报异常StopIteration

迭代器

迭代器对象为一次性消费,用完不可再生,

如果要使用,需要重新拿到迭代器,

两个迭代器之间无干扰。

栗子

list1 = [1, 2, 3, 4, 5]

it1 = iter(list1)
print(next(it1)) #1
print(next(it1)) #2

print("\nfor loop")
for x in it1:
    print(x)

#3
#4
#5

print("\nNo interference between two iters")
it2 = iter(list1)
it3 = iter(list1)
print(next(it2)) #1
print(next(it3)) #1
print(next(it2)) #2
print(next(it3)) #2

迭代器对象是一个可迭代对象又是一个迭代器对象,调用可迭代接口(__iter()__)返回它自身。

可迭代对象每次都创建一个迭代器。

解决思路

STEP1:实现一个迭代器对象WeatherIterator,__next__每次返回一个城市的气温信息

STEP2:实现一个可迭代对象WeatherIterable,__iter__方法返回一个WeatherIterator对象

代码:

from collections import Iterable, Iterator
import requests

class WeatherIterator(Iterator):
    def __init__(self, cities):
        self.cities = cities
        self.index = 0

    def __next__(self):
        if self.index == len(self.cities):
            raise StopIteration
        city = self.cities[self.index]
        self.index += 1
        return self.get_weather(city)

    def get_weather(self, city):
        url = 'http://wthrcdn.etouch.cn/weather_mini?city=' + city
        r = requests.get(url)
        data = r.json()['data']['forecast'][0]
        return city, data['high'], data['low']

class WeatherIterable(Iterable):
    def __init__(self, cities):
        self.cities = cities

    def __iter__(self):
        return WeatherIterator(self.cities)

def show(w):
    for x in w:
        print(x)

w = WeatherIterable(['北京', '上海', '广州'] * 10)
show(w)

参考资料:python3实用编程技巧进阶

猜你喜欢

转载自www.cnblogs.com/marton/p/10754241.html