搜索
首页后端开发Python教程Python详细解析之容器、可迭代对象、迭代器以及生成器

本篇文章给大家带来了关于python的相关知识,其中主要介绍了关于容器、可迭代对象、迭代器以及生成器的相关问题,下面就一起来看一下,希望对大家有帮助。

Python详细解析之容器、可迭代对象、迭代器以及生成器

推荐学习:python视频教程

在刚开始学Python的时候,是不是经常会听到大佬们在讲容器、可迭代对象、迭代器、生成器、列表/集合/字典推导式等等众多概念,其实这不是大佬们没事就搁那扯专业术语来装B,而是这些东西都得要明白的,光知道字符串、列表等基础还是不够的,尤其是在Python的数据结构方面。

今天就来给大家讲讲Python中的容器、可迭代对象、迭代器和生成器这些难理解的概念,让你的Python基础更上一层楼!

一、容器

1.什么是容器?

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

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

当然了,它不是我创造的,我没有那么大本事哈,是官方创造的好吧,你也不用担心我是在教你一些奇奇怪怪的名词,说出去别人都听不懂…python中都是这么叫的。常见的容器类型有列表(list)、元组(tuple)、字符串(str)、字典(dict)以及集合(set )

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


二、可迭代对象

1.什么是可迭代对象?

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

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

注意两个点:

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

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

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

在这里插入图片描述

其实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步

输出结果:

在这里插入图片描述

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

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

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

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

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

在这里插入图片描述

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

三、迭代器

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

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

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

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

在这里插入图片描述


四、序列

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

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

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

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

在这里插入图片描述

通过这个例子我们可以看出来,只要执行一次,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倍:

在这里插入图片描述

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

在这里插入图片描述

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

在这里插入图片描述

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

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

在这里插入图片描述

[] 换成()之后,返回的是一个生成器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))

运行结果:

111213

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

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

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

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

七、小结

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

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

在这里插入图片描述

推荐学习:python教程

以上是Python详细解析之容器、可迭代对象、迭代器以及生成器的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:CSDN。如有侵权,请联系admin@php.cn删除
您如何切成python阵列?您如何切成python阵列?May 01, 2025 am 12:18 AM

Python列表切片的基本语法是list[start:stop:step]。1.start是包含的第一个元素索引,2.stop是排除的第一个元素索引,3.step决定元素之间的步长。切片不仅用于提取数据,还可以修改和反转列表。

在什么情况下,列表的表现比数组表现更好?在什么情况下,列表的表现比数组表现更好?May 01, 2025 am 12:06 AM

ListSoutPerformarRaysin:1)DynamicsizicsizingandFrequentInsertions/删除,2)储存的二聚体和3)MemoryFeliceFiceForceforseforsparsedata,butmayhaveslightperformancecostsinclentoperations。

如何将Python数组转换为Python列表?如何将Python数组转换为Python列表?May 01, 2025 am 12:05 AM

toConvertapythonarraytoalist,usEthelist()constructororageneratorexpression.1)intimpthearraymoduleandcreateanArray.2)USELIST(ARR)或[XFORXINARR] to ConconverTittoalist,请考虑performorefformanceandmemoryfformanceandmemoryfformienceforlargedAtasetset。

当Python中存在列表时,使用数组的目的是什么?当Python中存在列表时,使用数组的目的是什么?May 01, 2025 am 12:04 AM

choosearraysoverlistsinpythonforbetterperformanceandmemoryfliceSpecificScenarios.1)largenumericaldatasets:arraysreducememoryusage.2)绩效 - 临界杂货:arraysoffersoffersOffersOffersOffersPoostSfoostSforsssfortasssfortaskslikeappensearch orearch.3)testessenforcety:arraysenforce:arraysenforc

说明如何通过列表和数组的元素迭代。说明如何通过列表和数组的元素迭代。May 01, 2025 am 12:01 AM

在Python中,可以使用for循环、enumerate和列表推导式遍历列表;在Java中,可以使用传统for循环和增强for循环遍历数组。1.Python列表遍历方法包括:for循环、enumerate和列表推导式。2.Java数组遍历方法包括:传统for循环和增强for循环。

什么是Python Switch语句?什么是Python Switch语句?Apr 30, 2025 pm 02:08 PM

本文讨论了Python版本3.10中介绍的新“匹配”语句,该语句与其他语言相同。它增强了代码的可读性,并为传统的if-elif-el提供了性能优势

Python中有什么例外组?Python中有什么例外组?Apr 30, 2025 pm 02:07 PM

Python 3.11中的异常组允许同时处理多个异常,从而改善了并发场景和复杂操作中的错误管理。

Python中的功能注释是什么?Python中的功能注释是什么?Apr 30, 2025 pm 02:06 PM

Python中的功能注释将元数据添加到函数中,以进行类型检查,文档和IDE支持。它们增强了代码的可读性,维护,并且在API开发,数据科学和图书馆创建中至关重要。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。