虽然都说Python简单,但是如果你没有语言基础,还没有老师教,那学习路线就异常曲折了,虽说有度娘,但上面的文章都是你抄我我抄你,能有几个人自己一个个码子上去?还有一点,即便你历经万难,从垃圾堆里翻出来一本《论语》,打开一看,一脸懵逼,这么复杂的天书谁能看懂,顿时泄气。
我也是刚刚学习Python不久,每当学到一个重要的点,或者复杂的点,就自己用大白话写一些心得出来,自己总结一遍,别人看的也舒服。如果能帮助新手少走弯路那就功不可没了。话不多说,这次我俩介绍Python中的生成器,迭代器,可迭代对象,这能把很多新人都搞迷糊。
生成器(生成器函数)、迭代器是个什么鬼?
先说下我对我两个器械的理解,既然叫做器,那跟法器、武器、容器一样,是个工具,Python内部的工具。
这两个工具的最大作用是节约计算机内存占用,比如展现一个上亿元素的列表并计算,
sum([i*i for i in range(1000000000)])
内存小的机器肯定要宕机。
为了解决这个问题,Python中出现了生成器和迭代器,这两个东西不再无限制的展现和计算元素,而是保存算法。
当你用next()调用,他计算下一个元素,再调用next(),再计算下一个元素,这样极大的节约内存空间,如果有台486的机器能运行Python,并且计算上亿元素一样能胜任。
比如把上面的例子改成这样:
sum(i*i for i in range(1000000000))少了个[]就不会宕机了
理解Python中的生成器、迭代器以及可迭代对象,需要死记硬背几个概念,就像《公司法》一样,就是这么规定的,要开公司必须遵守,要用Python也必须遵守。
把列表解析中的[],换成()就实现了生成器(如上面求和的例子);
函数中包含yied,就实现了生成器函数(下面举例)
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
生成器(generator)都是迭代器(iterator)对象。
list,dict,set,str,generator(生成器),iterator(迭代器),全部都是可迭代对象(英语叫Iterable)。
可迭代对象都可以使用for循环遍历。
生成器
咱们构造一个生成器,比如小括号的一个列表生成式,这就是一个简单的生成器。
g=(x for x in range(10)) at 0x7f25fb86eb40>>>> isinstance(g,Iterator)返回True,生成器都是迭代器对象。
再来构造一个生成器函数,功能是统计一个列表里单词出现的位置。
ls=['no','yes','no','noby','other']#一个列表def shengchengqi(text):#这种带yieled的函数就被称为生成器函数 if text: yield '成功读取文本' for i,o in enumerate(text,1): if o=="no": yield iprint([s for s in shengchengqi(ls)])结果['成功读取文本', 1, 3]
看看这个函数的类型
print(isinstance(shengchengqi(ls),Iterator))返回TURE,生成器都是迭代器对象。
迭代器和可迭代对象
这个算是重头了,里面包含的内容比较多,我用简单的方式解释我的理解。
当你用for循环一个列表(可迭代对象),咔咔一堆结果出来了,你没看到操作过程,只看到结果,要理解迭代器就要明白Python在后台是怎么操作的。
他先取找列表有没有._iter()方法,(列表当然后,你要是自创一个,肯定没有!)如果有就使用该方法把列表变成一个迭代器,
>>> l=[1,2,3,4]>>> y=l.__iter__()
y是一个迭代器
接下来,Python继续调用y的next方法,不停歇,直到最后报错。
>>> y.__next__()1>>> y.__next__()2>>> y.__next__()3>>> y.__next__()4>>> y.__next__()Traceback (most recent call last): File "", line 1, in StopIteration
如果现在还没明白,我用一个实际例子讲解,自创迭代器和迭代对象,实现读取各地城市天气存入迭代器。
根据上面说的,要实现这个功能,要创造一个迭代器和一个可迭代对象,继承Python默认类。
第一步,创造WeatherIterable类,告诉Python这是一个可迭代对象。
class WeatherIterable(Iterable):#继承默认可迭代类 def __init__(self,cities):#构造城市列表 self.cities=cities def __iter__(self):#给他iter方法,返回迭代器 return WeatherIterator(self.cities)
第二步,创造迭代器类,包含抓取天气,和next方法。
class WeatherIterator(Iterator):#继承默认迭代器类 def __init__(self,cities): self.cities=cities#构造城市列表 self.index=0#必须要有个索引值 def getweather(self,city):#requests抓天气 rs = requests.get('http://wthrcdn.etouch.cn/WeatherApi?city={}'.format(city)) today = re.match(r'.*(.*?).*?(.*?).*?(.*?)', rs.text) return ",,,".format(city, today.group(1), today.group(2), today.group(3)) def __next__(self):#next要实现的功能 if self.index==len(self.cities): raise StopIteration city=self.cities[self.index] self.index+=1 return self.getweather(city)
第三步,创造已经完成,要使用,三种方式都ok。
y=iter(WeatherIterable(('长春','吉林','北京','广州')))print(next(y))结果:长春,17日星期二,高温 9℃,低温 -2℃for i in iter(WeatherIterable(['深圳','杭州'])): print (i)结果:深圳,17日星期二,高温 29℃,低温 22℃杭州,17日星期二,高温 19℃,低温 15℃for t in WeatherIterable(('长春','吉林','北京','广州')): print(t)结果:长春,17日星期二,高温 9℃,低温 -2℃吉林,17日星期二,高温 9℃,低温 0℃北京,17日星期二,高温 16℃,低温 11℃广州,17日星期二,高温 27℃,低温 20℃
用个知乎提结束吧,“以上,再多说无益。”
领取专属 10元无门槛券
私享最新 技术干货