📌Python编程基础--Chapter07数据结构下
- 一、概述
- 二、列表
- 1、列表的创建
- 2、列表的使用
- 3、列表特有操作及常用方法
- 5、函数作为列表的元素
- 三、元组
- 1、元组的创建
- 2、元组常用方法
- 3、元组用途
- 四、字典
- 1、创建字典
- 2、字典的访问
- 3、字典常用方法
- 4、字典的排序
- 五、集合
- 1、集合的创建
- 2、集合比较
- 3、集合逻辑运算
- 4、集合的方法(面向所有集合)
- 5、集合的方法(面向可变集合)
- 六、推导式
- 1、推导式基本语法
- 2、生成器推导式
- 3、列表推导式应用实例
- 七、迭代器
- 八、可变类型和不可变类型
- 九、关于复制
一、概述
-
在前面的章节中,我们学习了基本数据类型,包括数值类型、字符串类型、布尔类型等,这些类型能表示一个数据,这种表示单一数据的类型称为基本数据类型。
-
实际在计算中,计算机不仅能处理单个变量表示的数据,更多情况下,计算机需要对一组数据进行批量处理,这就需要能表示多个数据的组合数据类型。
组合类型的种类
- 列表
- 元组
- 字典
- 集合
二、列表
- 列表是Python中非常重要的数据类型,通常作为函数的返回类型。
- 列表由一组元素组成。列表可包含任何类型的值:数字、字符串甚至序列。
- 列表是可变的,即可以在不复制的情况下添加、删除或修改列表元素。
1、列表的创建
- 格式:
lst=[元素1,元素2,…元素n] #定义n个元素组成的列表
lst=[] #定义空列表
lst=[x] #定义只包含一个元素的列表
lst=list([可迭代参数])
-
说明:
列表用方括号括起,其中元素用逗号分隔。 -
列表的形式
例7-1:创建列表
2、列表的使用
列表也是序列,其使用与字符串十分相似,同样支持正、负索引、切片等特性,但列表的元素可修改。
与字符串一样,可使用len获取列表长度,还可使用+和*拼接列表。
例7-2:列表的使用
3、列表特有操作及常用方法
注意:以上列表操作中的切片范围均不包括第j个元素本身。
例如:
列表常用方法
注意:
所有适用于序列的函数均适用于列表。
调用列表方法之后会改变原列表。
列表操作方法的语法形式是:
<列表变量>.<方法名称>(<方法参数>)
例7-3:在列表末尾添加元素或列表
例7-4:列表的查找、排序和反转
例7-5:用列表实现堆栈(“后进先出”的线性表)
例7-6:用列表实现队列(“先进先出”的线性表)
例7-7:有两个元素为整数的列表,删除列表1中与列表2的重复元素。
例7-8:列表应用
- 某学校组织了一场校园歌手比赛,每个歌手的得分由10名评委和观众决定,最终得分的规则是去掉10名评委所打分数的一个最高分和一个最低分,再加上所有观众评委分数后的平均值。评委打出的10个分数为:9、9、8.5、10、7、8、8、9、8和10,观众评委打出的综合评分为9,请计算该歌手的最终得分。
C++源程序:
Python源程序:
5、函数作为列表的元素
用函数作为参数与列表一起使用非常有用,也称为高阶编程。
例7-9:假定L是一个列表,f是一个函数,用函数替换每个元素改变列表,即用f(e)改变L中的元素e。
课堂练习一:
三、元组
- 元组由一组元素组成。元组可包含任何类型的值:数字、字符串甚至序列。
- 元组是一种不可变序列,即创建之后不能再做任何修改。
- 元组通常代表一行数据,而元组中的元素代表不同的数据项。
1、元组的创建
- 格式:
tpl=(元素1,元素2,…元素n) #定义n个元素组成的元组
tpl=() #定义空元组
tpl=(元素1,) #定义单元素元组
tpl=tuple([可迭代参数])
- 说明:
元组用圆括号括起(也可以不加圆括号),其中元素用逗号分隔。
2、元组常用方法
说明:
所有适用于序列的函数均适用于元组
元组没有列表所常用的append、find方法
元组操作方法的语法形式是:
<元组变量>.<方法名称>(<方法参数>)
例7-16:元组方法应用
例17-11:编写函数求两个正整数的所有公约数,以元组形式返回结果
3、元组用途
在映射类型中当作键使用
函数的特殊类型参数
作为很多内置函数的返回值
四、字典
- 字典是Python重要的数据类型,字典是由“键—值”对组成的集合,字典中的“值”通过“键”来引用。
- 字典也称为关联数组、映射或散列表。
- Python字典利用了“哈希”方法,使用专门的哈希函数完成,即字典中的每个键都被转换为一个数字—哈希值。字典中值存储在一个底层列表中,并用哈希值作为索引。访问值时,将提供的键转为哈希值,再转到列表的相应位置。使用“键”来访问字典值效率极高。
- 字典的键必须是可哈希对象,可哈希对象是指拥有
__hash__(self)
内置方法的对象。列表、可变集合和字典类型的数据不是可哈希对象,所以它们不能作为字典中的键。数值、字符串、元组和不可变集合都是可哈希对象,因此可以作为字典的键。 与列表相同,字典也是可以改变的,可以添加、删除或修改“键—值”对。
字典的排列顺序不确定。
1、创建字典
格式:
dictionary={key1:value1, key2:value2, …, keyn:valuen}#创建n个“键—值”对组成的字典
dictionary=dict(参数)
dictionary={} #创建空字典
dictionary=dict() #创建空字典
dict函数的参数说明:
参数可以是如下之一:
- 键-值对
- 1或多个赋值表达式
- zip函数返回的结果
- 元组列表,每个元组包含两个元素,分别对应键和值
- 一个已有的字典
例如:
注意:
- 对于字典的键有两个限制:
- 字典中的键必须独一无二,即在同一个字典中,任何两个键—值对都不能相同。若为同一键值多次定义了不同的元素值,按照字典中此键值出现的顺序,只取最右侧的一对“键:值”。
- 键必须是不可变的(可哈希的)。因此,字典键不能是列表、字典、可变集合
- 对值没有这两个限制。
2、字典的访问
- 字典的访问与元组、列表有所不同,元组和列表是通过数字索引获取对应的值,而字典是通过key值获取相应的value值。
- 格式:
value=dictionary[key]
- 说明:
- 字典的添加和修改只需执行一条赋值语句即可,例如:dictionary[x]=value
- 字典的删除虽没有类似列表的remove操作,但可调用内置函数del()完成删除字典元素(字典带有pop和clear方法,也可以完成删除的功能)。
例7-12:字典的创建、添加、删除和修改
3、字典常用方法
说明:
- popitem()返回并删除字典的某个键—值对,具体是哪个预先并不知道,因此仅当不在乎字典元素的顺序时,此函数才适用。
- items()、keys()和values()都返回一个特殊对象—视图。视图被链接到原始字典,因此若字典发生变化,视图也将相应地变化。
- 字典操作方法的语法形式是:
<字典变量>.<方法名称>(<方法参数>)
例7-13:字典方法应用一
例7-14:字典方法应用二
4、字典的排序
- 字典的排序可以使用内置函数sorted()实现(该函数可对列表、元组、字典进行排序,都不改变原对象)。
sorted(iterable, key=None, reverse=False) --> new sorted list
- 对于字典,此处:
- iterable—字典的键-值对
- Key—排序关键字:键或值
- reverse—升序或降序,True为降序,False为升序,默认升序
例7-15:字典排序
课堂练习二:
五、集合
- 在Python中,集合类似于字典,但只包含键,而没有相关联的值。
- 与字典一样,集合的元素排列顺序也是不确定的,但不允许有相同元素且元素必须是可哈希(hashable)的对象。
- 可哈希对象是指拥有
__hash__(self)
内置方法的对象。列表、可变集合和字典类型的数据不是可哈希对象,所以它们不能作为集合中的键。数值、字符串、元组和不可变集合都是可哈希对象,因此可以作为集合的键。
Python中集合的类别:
- 集合分两类:可变集合(set)和不可变集合(frozenset)。对于可变集合,可添加和删除元素,而不可变集合一旦创建就不能更改。
- 在Python中,集合是相对较新的功能,在其还不支持集合时,一般使用字典模拟集合。
- 集合没有列表和字典用得多,本章简要介绍,详细内容可参阅:https://docs.python.org/3/library/stdtypes.html#set
1、集合的创建
- 集合中的所有元素都写在一对大括号“{}”中,各元素之间用逗号分隔。
- 创建集合时,既可以使用{},也可以使用set函数。
- set函数的语法格式:set([iterable])
- 其中,iterable是一个可选参数,表示一个可迭代对象(包括:字符串、列表、元组、字典、集合)。
- set函数只能有一个参数或者无参。
- 注意:想要创建空集合,必须使用 set() 而不是{}。
例7-17:创建集合
2、集合比较
3、集合逻辑运算
例7-18:集合关系运算
4、集合的方法(面向所有集合)
说明:s、t集合运算后不会改变。
5、集合的方法(面向可变集合)
说明:运算之后s集合会改变。
六、推导式
- 推导式是从一个或者多个迭代器快速简洁地创建数据结构的一种方法
- 将循环和条件判断结合,从而避免语法冗长的代码
- 可以用来动态地生成列表、字典和集合
1、推导式基本语法
列表推导式:
[<表达式> for <变量> in <可迭代对象> if <逻辑条件>]
字典推导式:
{<键值表达式>:<元素表达式> for <变量> in <可迭代对象> if <逻辑条件>}
集合推导式:
{<元素表达式> for <变量> in <可迭代对象象> if <逻辑条件>}
例如:
2、生成器推导式
- 与推导式语法相同:
(<元素表达式> for <变量> in <可迭代对象> if <逻辑条件>)
- 返回一个生成器对象,也是可迭代对象
- 但生成器并不立即产生全部元素,仅在要用到元素的时候才生成,可以极大节省内存
- 如果生成的序列比较复杂,可使用生成器函数(详见第五章模块和函数)
例如:
3、列表推导式应用实例
例7-19:用普通方法和列表推导式方法分别创建一个由1~10的平方组成的列表
例7-20:生成列表,将1-10中的每个数字翻倍并加上7
例7-21:在列表推导式中使用字符串
例7-22:利用列表推导式修改现有列表
例7-23:利用列表推导式进行筛选,返回列表中的正数
例7-24:利用列表推导式删除字符串中的所有元音
七、迭代器
- 可迭代对象(Iterable)—可直接使用for循环遍历的对象统称为可迭代对象。
- 迭代器(Iterator)指有
__iter__( )
方法和__next__( )
方法的对象,可以通过next函数不断获取下一个值,并不是所有的可迭代对象都是迭代器。 - 可以使用isinstance方法判断一个对象是否是可迭代对象或迭代器。
- 对于可迭代对象,可以通过iter函数得到迭代器。
- 对于迭代器,则可以使用next函数不断获取下一个元素,当所有元素都获取完毕后再调用next函数,就会引发StopIteration异常。
例7-25:可迭代对象和迭代器示例
例7-26:利用iter函数将可迭代对象转换为迭代器
例7-27:迭代器的next函数应用
八、可变类型和不可变类型
- 可变类型—即可以对该类型对象中保存的元素值做修改,如列表、字典、可变集合都是可变类型。
- 不可变类型—即该类型对象所保存的元素值不允许修改,只能通过给对象整体赋值来修改对象所保存的数据。但此时实际上就是创建了一个新的不可变类型的对象、而不是修改原对象的值,如数字、字符串、元组、不可变集合都是不可变类型。
说明:
- 可变类型的对象和不可变类型的对象的区别在于是否可修改对象中的元素值。
- 对于可变类型的对象,如果对可变类型对象中的元素做修改,则不会创建新对象;而如果直接对其赋值,则也会创建一个新的对象。
- 对于数字、字符串对象,创建一个新的等值对象,实际是引用原对象;对于列表、元组、字典、集合等对象,创建一个新的等值对象则是创建一个新对象。
例7-28:可变类型和不可变类型示例
执行结果:
九、关于复制
- 复制分为深拷贝和浅拷贝。
- 赋值:简单地拷贝对象的引用,两个对象的id相同。
深拷贝
:能够拷贝对象内部所有数据和引用,两个对象的id不同。引用相当于C语言中指针的概念,Python并不存在指针,但是变量的内存结构是通过引用来维护的。浅拷贝
:并不复制对象内部所有引用,只复制所有数据,两个对象的id不同。
说明:
- 浅拷贝和深拷贝的不同仅仅是对组合对象而言,所谓的组合对象就是包含了其它对象的对象,如列表、元组、字典、类实例等又包含了这些数据类型。
- 对于非组合类型,如:列表中只包含数字或字符串等原子类型的数据,深浅拷贝并无区别,一律生成另一个对象。
- 而对于组合对象而言,浅拷贝的副本肯定是另外一个对象,但其中的元素还是指向相同的对象,也就是说其中的元素还是一份;深拷贝是指创建一个新的对象,然后递归的拷贝原对象所包含的子对象。深拷贝出来的对象与原对象没有任何关联。
- 对于数字、字符串等原子类型对象,无论深浅拷贝生成的都是对原对象的引用。
实现浅拷贝和深拷贝的方法:
- 常见的浅拷贝有:切片操作、工厂函数(list,str,tuple)、对象的copy()方法、copy模块中的copy函数。
- 可使用copy模块来实现组合对象的深拷贝和浅拷贝。
- deepcopy()用于深拷贝
- copy()用于浅拷贝
例如:对元素类型为原子类型的拷贝操作
例7-29:组合对象的浅拷贝
例7-30:组合对象的深拷贝
整理不易🚀🚀,关注和收藏后拿走📌📌欢迎留言🧐👋📣✨
欢迎专注我的公众号:AdaCoding 和 Github:AdaCoding123