迭代器与生成器

可迭代对象: 列表,字典,元组等等 , 可迭代对象都满足__iter__()  这个方法

iter(): 有可迭代对象可以得到迭代器对象 , 迭代器满足 .next()  

1 实现一个迭代器对象:

# 迭代器,next方法每次返回一个城市气温
import requests
from collections import Iterator,Iterable
def getweather(city):
    r = requests.get("http://wthrcdn.etouch.cn/weather_mini?city=" + city)
    data = r.json()['data']['forecast'][0]
    return  "%s : %s , %s" % (city,data['low'],data['high'])
#print(getweather("北京"))
# 迭代器
city_ls = ["北京","上海","张家口","东北"]
class witerator(Iterator):
    def __init__(self,citys):
        self.citys = citys
        self.index = 0
    def __next__(self):
        if self.index == len(self.citys):
            raise StopIteration               # 如果迭代完返回异常
        city = self.citys[self.index]
        self.index += 1
        r = getweather(city)
        return r

# 可迭代
class witerable(Iterable):
    def __init__(self,citys):
        self.citys = citys
    def __iter__(self):
        return witerator(self.citys) # 返回迭代器

#实例化
ret = witerable(city_ls)
for x in ret:
    print(x)

 

#生成器 : 包含yield 的是生成器, 执行返回一个生成器对象 支持next 方法获取一个值

通过生成器实现可迭代对象

# 生成器
#判断之间的一个数是不是素数
class p_n():
    def __init__(self,start,end):
        self.start = start
        self.end = end
    # 判断素数
    def ispnum(self,k):
        if k < 2:
            return False
        for i in range(2,k):
            if k % i == 0:
                return False
            return True
    def __iter__(self):
        for k in range(self.start,self.end):
            if self.ispnum(k):          # 如果是真返回k
                yield k

for x in p_n(1,100):
    print(x)

 

# 如何进行反向迭代

reversed() : 实现一个反向迭代器

列表的反向迭代
l = [1,2,3,4,5]
for i in reversed(l):
    print(i)
class f_r():
    def __init__(self,start,end,step):
        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):
        e = self.end
        while e >= self.start:
            yield e
            e -= self.step

for i in reversed(f_r(1,100,2)):
    print(i)

 

如何对迭代器做切片操作

使用itertools. islice 方法实现切片

l = [1,2,3,4,5]
from itertools import islice
r = islice(l,2,4) # 返回一个生产器对象
for x in r:
    print(x)

 

迭代多个可迭代对象

学生成绩存放在3个列表, 如同时迭代三个列表,计算学生总分

可以使用zip 能将多个可迭代对象合并,每次碟贩返回一个元组

或itertools .chain 他能将多个迭代对象链接

# 生产三个随机列表
from random import  randint
y = [randint(50,90) for _ in range(30)]
s = [randint(50,90) for _ in range(30)]
j = [randint(50,90) for _ in range(30)]
totle = []
for y_n,s_n,j_n in zip(y,s,j):
    totle.append(y_n + s_n + j_n)
print(totle)

# 生产三个随机列表
from random import randint
y = [randint(50,90) for _ in range(30)]
s = [randint(50,90) for _ in range(30)]
j = [randint(50,90) for _ in range(30)]
# 将多个可迭代变为一个
from itertools import chain
#成绩大于85的人数
count = 0
for i in chain(y,s,j):
if i > 85:
count += 1
print(count)
 

 

 

 

posted @ 2022-07-11 22:59  huxl1  阅读(20)  评论(0编辑  收藏  举报