# 列表和字符串都是可迭代對象
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