python基础四

作者: 小新你蜡笔呢 | 来源:发表于2018-09-13 20:10 被阅读0次

    1、可迭代对象

    首先思考一个问题,什么类型是可以for循环的。

    你会说有list,tuput,str,dict,set等等。他们有一个共性,就是都含有__iter__方法。

    说明他们都是可迭代的对象,有兴趣的可以在pycharm打断点,看一下for循环内部是如何实现的。

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

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

    2、迭代器

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

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

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

    3、生成器

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

    为什么学习生成器?

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

    3.1、生成器函数

    一个简单的生成器函数

    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个开始取值。

    3.2、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__一样,也是会报错,所以也不能接收值。

    3.3、yield from(python3版本)

    def zhangsan():

        a = "11"

        b = "22"

        c = "33"

        yield from a

        yield from b

        yield from c

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

    3.4生成器表达式

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

    print(ret)

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

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

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

    相关文章

      网友评论

        本文标题:python基础四

        本文链接:https://www.haomeiwen.com/subject/dgyggftx.html