# 列表和字符串都是可迭代对象
l = [1,2,3,4]
s = 'abcde'
for x in l:print(x)
for x in s:print(x)
iter(l)
iter(s)
l.__iter__()
# 迭代器对象
t = iter(l)
next(t)
next(t)
next(t)
t2 = iter(s)
next(t2)
next(t2)
''' 从网络抓取各个城市气温,并依次显示: 北京:12-16 上海:20-30 ... 若是一次抓取全部城市天气再显示,显示第一个城市气温时,有很高的延时,而且浪费存储空间,咱们指望以'用时访问的策略', 而且能把全部城市气温封装到一个对象里,可用for语句进行迭代,如何解决? '''javascript
import requests
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'])
getWeather('北京')
getWeather('上海')
from collections import Iterable,Iterator
# 可迭代对象抽象接口
Iterable.__abstractmethods__
# 迭代器对象抽象接口
Iterator.__abstractmethods__
import requests
from collections import Iterable,Iterator
class WeatherIterator(Iterator):
'''实现一个迭代器对象WeatherIterator'''
def __init__(self,cities):
self.cities = cities
#记录迭代位置
self.index = 0
def getWeather(self,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'])
def __next__(self):
'''__next__方法每次返回一个城市气温'''
if self.index == len(self.cities):
raise StopIteration
city = self.cities[self.index]
self.index += 1
return self.getWeather(city)
class WeatherIterable(Iterable):
'''实现一个可迭代对象WeatherIterable'''
def __init__(self,cities):
self.cities = cities
def __iter__(self):
'''__iter__方法返回一个迭代器对象'''
return WeatherIterator(self.cities)
for city in WeatherIterable(['北京','上海','广州','深圳']):
print(city)
''' 实际案例: 实现一个可迭代对象的类,它能迭代出给定范围内的全部素数: pn = PrimeNumber(1, 30) for k in pn: print kcss
输出结构: 2 3 5 7 11 13 17 19 23 29html
解决方案: 将该类的iter方法实现成生成器函数,每次yield返回一个素数 '''html5
def f():
print('in f(),1')
yield 1
print('in f(),2')
yield 2
print('in f(),3')
yield 3
g = f()
print(g.__next__())
print(g.__next__())
print(g.__next__())
'''生成器对象即实现了可迭代对象接口,又实现了迭代器接口'''
g = f()
for x in g:
print(x)
g.__iter__() is g
# 使用生成器返回全部素数
class PrimeNumbers:
def __init__(self,start,end):
self.start = start
self.end = end
def isPrimeNum(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+1):
if self.isPrimeNum(k):
yield k
for x in PrimeNumbers(1,100):
print(x)
''' 实际案例: 实现一个连续浮点数发生器FloatRange(和xrange相似), 根据给定范围(start, end)和步进值(step)产生一系列连续浮点数, 如迭代FloatRange(3.0, 4.0, 0.2)可产生序列 '''java
l = [1,2,3,4,5]
l.reverse()# 会改变原列表
# 切片操做,返回新的列表,可是浪费资源
l1 = l[::-1]
# 列表的反向迭代器,与iter()对应
reversed(l)
for x in reversed(l):
print(x)
# 实现正向和反向连续浮点序列
class FloatRange:
def __init__(self,start,end,step=0.1):
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.0,4.0,0.5):
print(x)
for x in reversed(FloatRange(1.0,4.0,0.5)):
print(x)
f = open('Alice.txt')
ls_lines = f.readlines()
# 会把文件指针移动到了文件最后
cut_lines = ls_lines[1:5]
print(cut_lines)
# readlines会把整个文件导入到内存当中,文件过大时会出现内存不足
# islice能返回一个迭代对象切片的生成器
from itertools import islice
islice(f,100,300)
f.seek(0)# 把文件指针移动到文件最前
for line in islice(f,20,25):
print(line)
islice(f,30)#前30行
islice(f,50,None)#50-最后一行
l = range(20)
#生成l的迭代器
t = iter(l)
#每次使用islice时,要从新申请一个可迭代对象,它会消耗这个迭代对象的资源
for x in islice(t,5,10):
print(x)
#t已经迭代到位置10
for x in t:
print(x)
''' 实际案例: 1.某班学生期末成绩,语文,数学,英语分别存储在3个列表中, 同时迭代三个列表,计算每一个学生的总分.(并行)node
解决方案: 并行: 使用内置函数zip,它能将多个可迭代对象合并,每次迭代返回一个元组. '''python
from random import randint
chinese = [randint(60,100) for _ in range(40)]
math = [randint(60,100) for _ in range(40)]
english = [randint(60,100) for _ in range(40)]
# 使用索引
# 局限:若是不是列表,而是生成器的话,将不能用索引访问
t = []
for i in range(len(chinese)):
t.append(chinese[i] + math[i] + english[i])
print(t)
# 使用zip()函数
total = []
for c,m,e in zip(chinese,math,english):
total.append(c + m + e)
print(total)
''' 实际案例: 2.某年及有4个班,某次考试每班英语成绩分别存储在4个列表中, 依次迭代每一个列表,统计全学年成绩高于90分人数.(串行)jquery
解决方案: 串行: 使用标准库中的itertools.chain,它能将多个可迭代对象链接. '''linux
from random import randint
from itertools import chain
c1 = [randint(60,100) for _ in range(40)]
c2 = [randint(60,100) for _ in range(41)]
c3 = [randint(60,100) for _ in range(42)]
c4 = [randint(60,100) for _ in range(43)]
count = 0
for s in chain(c1,c2,c3,c4):
if s > 90:
count += 1
count