迭代器
迭代类似于循环,每一次重复的过程称为迭代,每一次迭代的结果会被用作下一次迭代的初始值。提供迭代的方法被称为迭代器
for i in 'asdc':
print(i)
for的作用是触发这个迭代器的迭代功能,字符串是容器也是迭代器,每次从容器里依次拿出一个数据,就是迭代操作。
对容器对象调用iter()方法可以得到迭代器,调用next()迭代器会返回下一个值
s = 'abcd'
t = iter(s)
while True:
try:
item = next(t)
except StopIteration:
break
print(item)
容器是迭代器则必须实现__iter__() 方法,返回迭代器本身,然后__next__()方法,规定了迭代的规则,一般迭代器需要我们自己定义类然后实现相应的方法
Iterator是迭代器类,而Iterable是接口
凡是可以for循环的,都是Iterable
凡是可以next()的,都是Iterator
Python中集合数据类型如list,truple,dict,str,都是Itrable不是Iterator,但可以通过iter()函数获得一个Iterator对象
Python中的for循环就是通过next实现的
迭代器的魔方方法:
__iter__()
__next__()
eg:构造迭代器,显示城市气温
from collections import Iterable, Iterator
import requests
class weatherIterator(Iterator):
def __init__(self, cities):
self.cities = cities
self.index = 0
def getWeather(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'])
def __next__(self):
if self.index == len(self.cities):
raise StopIteration
city = self.cities[self.index]
self.index += 1
return getWeather(city)
class weatherIterable(Iterable):
def __init__(self,cities):
self.cities = cities
def __iter__(self):
return weatherIterator(self.cities)
for x in weatherIterabale([u'北京', u'太原', u'绵阳', u'济宁']):
print(x)
北京: 低温 11℃, 高温 24℃
太原: 低温 10℃, 高温 35℃
绵阳: 低温 19℃, 高温 32℃
济宁: 低温 19℃, 高温 32℃
对迭代器作切片操作
f = open('english.txt').readlines()
f[1:2]
#弊端:readlines一次性读入所有数据,如果数据量太大,消耗的内存将会增多
f = open('english.txt')
data = islice(f, 10,15)
for line in data:
print(line)
data: <itertools.islice at 0x110036f98>
迭代器实现斐波那契数列:
class f:
def __init__(self, n=20):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
self.a, self.b = self.b, self.a+self.b
if self.a > self.n:
raise StopIteration
return self.a
fib = f()
for each in fib:
print(each)
生成器
迭代器需要定义一个类和实现相关的方法,而生成器只需要在普通的函数上加上yield语句即可
正向,反向迭代器
class f:
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 i in f(1,5):
print(i, end=' ')
print()
for i in reversed(f(1,5)):
print(i, end= ' ')
1 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0
5 4.5 4.0 3.5 3.0 2.5 2.0 1.5 1.0
一次性迭代多个对象:
并行
chinese = [randint(60,100) for x in range(40)]
math = [randint(60,100) for x in range(40)]
english = [randint(60,100) for x in range(40)]
data = list(zip(chinese, math, english))
score = []
for x,y,z in data:
score.append(x+y+z)
串行
from itertools import chain
class1 = [randint(60,100) for x in range(40)]
class2 = [randint(60,100) for x in range(40)]
class3 = [randint(60,100) for x in range(40)]
class4 = [randint(60,100) for x in range(40)]
count = 0
for s in chain(class1, class2, class3, class4):
if s > 90:
count += 1
print(count)