前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python基础四

python基础四

作者头像
不断折腾
发布2019-09-23 10:26:43
3410
发布2019-09-23 10:26:43
举报

无论是风里,还是在雨里,我都在这里守候着你~

可迭代对象

首先思考一个问题,什么类型是可以for循环的。你会说有list,tuput,str,dict,set等等。他们有一个共性,就是都含有__iter__方法。说明他们都是可迭代的对象,有兴趣的可以在pycharm打断点,看一下for循环内部是如何实现的。

也就是说:含有__iter__方法的对象都是可迭代对象。

另:只有可迭代对象才可以for循环。

迭代器

再次思考一个问题,假如有一个列表,有很多数据,比如占用了4g,那我们在循环的时候会不会很占空间?我电脑内存一共就那莫大,还不说系统占用的内存。在可迭代对象中我们提到了for循环内部实际上也使用了迭代器,使用迭代器可以使在循环时不占用过多的内存,这就是迭代器的神秘之处。

概念:在可迭代对象的基础上再含有__next__方法。也就是同时含有__iter__和__next__方法。

反过来想,迭代器一定是可迭代对象。但可迭代对象不一定是迭代器。

生成器

看过我python爬虫教程的一定看到过生成器。可能看到的时候不知道他是生成器。

为什么学习生成器?

我们目前的返回值较少,当我们返回的内容较多时,我们使用生成器返回,以此来节省内存。

生成器函数

一个简单的生成器函数:

实例:

def zhangsan():

print("我是张三")

yield "张三"

print("我是李四")

yield "李四"

ret = zhangsan()

print(ret)

print(__item__ in dir(ret))

ret1 = ret.__next__()

print(ret1)

ret2 = ret.__next__()

print(ret2)

定义:当一个函数中有yield时,我们就称它为生成器函数。

yield:和return有一个共性就是也可以返回一个值(张三),不同的是,他并不代表一个函数的结束,为什么叫生成器函数?因为yield返回的是一个生成器。并且yield不能和return一起用。

结果:

ret = zhangsan() ----> <generator object zhangsan at 0x02A6FEA0>

print(__item__ in dir(ret)) ----> True

print(ret1) ----> 我是张三

----> 张三

print(ret2) ----> 我是李四

----> 李四

ret:返回的是一个生成器,并不会像ruturn那样接收到返回值.

print(ret1) ret1调用一次__next__()只会取到第一个返回值和执行第一个yield上的函数体。

print(ret2) ret2算第二次调用__next__(),会从上面的yield往下执行,以下以此类推。

另:其实我们没有必要调用__next__()方法来取值,直接for循环就可以了,我们自己调用__next__()方法,当超过了返回值的数量是会报错的。(我们还没有学到报错的解决方法)

修改成:

def zhangsan():

print("我是张三")

yield "张三"

print("我是李四")

yield "李四"

ret = zhangsan()

for i in ret:

print(i)

即可。

生成器的取值特点:生成器取值是要一次循环完的,比如一个生成器有100个值,我先取了50个值,那么我们再次取值的时候是接着上次的取值也就是从第51个开始取值。

send()

def zhangsan():

print("我是张三")

name = yield "张三"

print("name:",name)

print("我是李四")

yield "李四"

ret = zhangsan()

print(ret.__next__())

print(ret.send("123"))

结果:

我是张三

张三

name: 123

我是李四

李四

可以看出我们利用send(),在第二次取值的时候将yield "张三" 替换成了123

另:第一次必须使用__next__()调用,因为还没有赋值就已经返回了。那最后一个因为他的后面没有yield了,和__next__一样,也是会报错,所以也不能接收值。

yield from(python3版本)

def zhangsan():

a = "11"

b = "22"

c = "33"

yield from a

yield from b

yield from c

yield from :集体一个一个返回,不用再内部使用for循环一个一个返回。

生成器表达式

ret = (i for i in range(100))

print(ret)

输出:<generator object <genexpr> at 0x03784D50>

说明是一个装饰器。简单,但是也只能实现一些小功能。

另(列表生成式):列表也可以这样写:list = [i for i in range(100)],生成一个0到99的list。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python入门到放弃 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档