温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解Python的容器、可迭代对象、迭代器、生成器

发布时间:2021-10-12 10:09:52 来源:亿速云 阅读:141 作者:iii 栏目:开发技术

本篇内容主要讲解“如何理解Python的容器、可迭代对象、迭代器、生成器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何理解Python的容器、可迭代对象、迭代器、生成器”吧!

目录
  • 一、容器

    • 1.什么是容器?

  • 二、可迭代对象

    • 1.什么是可迭代对象?

  • 三、迭代器

    • 四、序列

      • 五、列表推导式

        • 六、生成器

          • 1.生成器的第一种创建方法:生成器表达式

          • 2.生成器的第二种创建方法:yield

        如何理解Python的容器、可迭代对象、迭代器、生成器

        一、容器

        1.什么是容器?

        在Python中,容器是把多种元素组织在一起的数据结构,容器中的元素就可以逐个迭代获取。说白了,它的作用就像它的名字一样:用来存放东西(数据)。

        容器实际上是不存在的,它并不是一种数据类型,只是人为的一种概念,只是为了方便学习所创造的一个概念词,它可以用成员关系操作符(in或not in)来判断对象是否在容器里面。

        当然了,它不是我创造的,我没有那么大本事哈,是官方创造的好吧,你也不用担心我是在教你一些奇奇怪怪的名词,说出去别人都听不懂…python中都是这么叫的。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        常见的容器类型有列表(list)、元组(tuple)、字符串(str)、字典(dict)以及集合(set )。

        既然容器里面的数据是可以迭代获取的,那么我们又得来学一个新概念:可迭代对象。

        二、可迭代对象

        1.什么是可迭代对象?

        在python中,可迭代对象并不是指某种具体的数据类型,它是指存储了元素的一个容器对象。

        也就是说,如果容器里面没有存储数据,那它就不是可迭代对象,并不是所有的容器都是可迭代对象,容器包含但并不仅限于可迭代对象。

        注意两个点:

        • 1.很多容器都是可迭代对象(容器包含了可迭代对象)。

        • 2.一个可迭代对象是不能独立的进行迭代的,迭代是通过for来完成的,凡是可迭代对象都可以直接使用for循环进行访问。

        for循环大家应该不陌生吧?有没有想过,for循环内部是怎么实现的?比如说这个for循环的例子,为什么能输出列表里的每一个元素?它的内部是怎么实现的?

        如何理解Python的容器、可迭代对象、迭代器、生成器

        其实for循环做了两件事情:

        • 1.使用 __iter__() 返回1个迭代器,迭代器在下面会讲,这里先知道有这么个东西。

        • 2.使用 __next__() 获取迭代器中的每一个元素。

        那么我们不用for循环来输出列表里的每一个元素,

        l = [1,2,3,4]
        # for i in l:
        #     print(i)
        ite =l.__iter__() #接收一下ietr()干了什么
        print(ite)  #打印
        print(ite.__next__())    #for循环干第2件事情的时候做的第1步
        print(ite.__next__())    #for循环干第2件事情的时候做的第2步
        print(ite.__next__())    #for循环干第2件事情的时候做的第3步
        print(ite.__next__())    #for循环干第2件事情的时候做的第4步

        输出结果:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        可以看出来,如果我们去掉哪行打印ite的代码,执行效果就是跟for循环输出列表里面的每一个元素是一样的,for循环里面限定了范围是4次,实际上就执行了1次__iter__()和4次__next__(),也就是说for循环访问迭代对象的本质就是通过这么去实现的。

        而且,for循环本质上干的那两件事情,缺一不可,也就是说如果没有__iter__()先返回了迭代器,__next()__也无法获取到元素,恰恰说明了前面说要注意的两点中的第2点:一个可迭代对象是不能独立的进行迭代的。

        有两个内置函数跟它们原理是一样的,本质相同,一般要用的话用内置函数要方便一些,起码不用写那么多下划线:

        • 内置函数 iter() 的本质是 __inter__() ,也是返回一个迭代器。

        • 内置函数 next() 的本质是 __next__(),也是有了迭代器之后获取元素。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        可以看出来结果也是一模一样的,既然讲到了迭代器,那么就来看看什么是迭代器。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        三、迭代器

        通过上面的for循环例子我们大概也能看得出来,

        • 只要是实现了__iter__()和__next__()的对象,就是迭代器,迭代器是一个可迭代对象。

        • 总之,迭代器是有__iter__()生成,可以通过__next__()进行调用。

        既然如此,我们在学Python基础的时候讲过range()是一个可迭代对象,那么它也是可以通过__iter__()生成一个迭代器的。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        四、序列

        序列在【赋值语句】那个专题文章中我有提过,这里再讲一下,序列也是一个抽象的概念,它包含了列表、元组和字符串,它本身是不存在的,也是便于学习所创造的一个概念词。

        可迭代对象包含序列,既然序列包含了列表、元组和字符串,前面我们的例子中也涉及到 了,所以说序列可以被iter()和next()使用。

        序列可以分为有限序列和无限序列。有限序列就是有范围的,比如说range(10)就已经限定了范围,相反的,无限序列也就是没有限定范围的序列。

        我们来生成一个无限序列,这里需要用到1个新模块itertools,itertools用于高效循环的迭代函数集合,它下面有一个方法count(),可生成迭代器且无范围,可以理解为无限迭代器。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        通过这个例子我们可以看出来,只要执行一次,next()就会获取一次迭代器里面的内容并逐次获取,我这里只写了4个next(),你多写几次就会多输出几次。

        像next()这种什么时候需要就什么时候调用的机制叫做懒加载机制,也叫懒汉式加载;

        相反地就有饿汉式加载。比如for循环这种的,只要一执行就会把可迭代器里面的所有对象都获取。

        五、列表推导式

        列表推导式跟生成器有关,在讲生成器之前,需要先知道什么是列表推导式,列表推导式就是生成列表的一种方法,语法是这样的:

        l = [i for i in 可迭代对象]

        i表示要放进列表里的对象,for循环是一个式子。

        比如我们用列表推导式来生成一个列表试试:

        l = [i for i in range(5)]
        print(l)

        运行结果:

        [0, 1, 2, 3, 4]

        运用列表推导式可以很方便地生成我们想要的列表。

        同时它也有很多灵活的用法,比如在后面加上条件判断

        l = [i for i in range(5) if 4<5]
        print(l)

        运行结果:

        [0, 1, 2, 3, 4]

        if后面的条件判断为真,则可以正常生成列表,如果为假,则列表推导式是无效的,此时的l将是一个空列表。

        还有其他灵活的用法,比如操作前面的i,比如让i的数值全都翻2倍:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        我们把迭代对象换一下,换成字符串,也同样可以输出,只是*在字符串里面表示重复操作符,所以效果变成了这样:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        不仅如此,前面的i*2我们还可以用函数来进行操作,比如:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        总而言之,列表推导式就是用来快速和自定义生成列表的一种方法,很灵活。

        那么有人可能会举一反三了,列表推导式都是用 [] 来进行操作的,那如果用()来操作行吗?它会不会生成一个元组?我们来看看:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        [] 换成()之后,返回的是一个生成器generrator ,那么下面我们再来讲讲生成器:

        六、生成器

        生成器是真实存在于Python中的对象,与容器这种概念词是不同的,它是可以直接通过next()进行调用的。

        1.生成器的第一种创建方法:生成器表达式

        第一种创建方法跟列表推导式是差不多的,就是 [] 换成了():

        l = (i for i in 可迭代对象)

        比如我们来生成一个生成器,看看能不能用next()直接调用:

        l = (i for i in "abcd")
        print(next(l))

        运行结果:

        a

        可以看出,生成器是可以直接调用的。那么既然生成器可以被next()调用,那么生成器就是一个特殊的迭代器,是一个可迭代对象。

        2.生成器的第二种创建方法:yield

        除了用上面那种方法创建生成器,还可以用yield来创建,方法如下:

        yield 关键字

        比如说我们用一个函数中包含yield来创建生成器:

        def fun():
            a = 10
            while 1:
                a += 1
                yield a
        
        
        b = fun()
        print(b)

        运行结果:

        <generator object fun at 0x000001F2AD95E900>

        结果就是生成了一个生成器,而且此时的函数fun()就已经不再是一个函数了,它是一个生成器,只要函数中出现了yield,函数就变成了生成器。

        为什么while循环没有一直执行?先不着急,我们输出看看:

        def fun():
            a = 10
            while 1:
                a += 1
                yield a
        
        
        b = fun()
        print(next(b))
        print(next(b))
        print(next(b))

        运行结果:

        11
        12
        13

        我调用了三次,所以它就运行了三次,while循环虽然存在,但是却不起作用,是因为前面我们提过的懒汉式加载。

        什么时候需要了,什么时候用next()调用,就是懒汉式加载,不像饿汉式加载那样,提前生成了所有对象,如果这里换成for循环来完成,比如:

        def fun():
            a = 10
            while 1:
                a += 1
                print(a)
        
        b = fun()

        运行之后程序将会进入死循环,一直给a自加1,你可以试试看效果,这就是饿汉式加载提前生成了迭代器并调用了全部迭代器对象,饿汉式加载占用资源的放大镜。

        如何理解Python的容器、可迭代对象、迭代器、生成器

        七、小结

        今天讲的内容可能听起来比较枯燥,这也是没得办法的,有些东西第一次听可能有点”难以下咽“,见得多了之后就习惯了,你得强迫自己去试着接受和理解这些抽象的东西。

        最后用一张图来总结一下它们的关系:

        如何理解Python的容器、可迭代对象、迭代器、生成器

        到此,相信大家对“如何理解Python的容器、可迭代对象、迭代器、生成器”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

        向AI问一下细节

        免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

        AI