Python 数据结构之 List and Tuple
关于 Python 基本数据类型,我们已经介绍了数字(Number)、字符串(String)。这一小节我们来看 Python 中的 元组(tuple)和列表(list)。
元组和列表都属于序列(Sequence),在开始介绍元组(tuple)和列表(list)之前我们需要先简单了解一下序列。
Python 中的序列
序列是一系列数据元素的集合,是 Python 中最基本的一种数据结构。
序列中的每个元素都分配一个 数字(指元素的位置,或索引),第一个索引是 0
,第二个索引是 1
,依此类推。每个索引对应一个元素。
Python 包含 6 中内建的序列,包括列表
、元组
、字符串
、Unicode 字符串
、buffer 对象
和 xrange 对象
。
对于序列,都可以使用以下操作:
- 索引
- 切片
- 加
- 乘
- 成员检查
- 计算序列的长度
- 取序列中的最大、最小值
你可以和我们前面介绍过的字符串(String)类型进行一一验证(都介绍过~~~)。
关于序列详细解读可以参见博文:Python 中的序列详解。
列表(List)
List(列表) 是 Python 中使用最频繁的数据类型。
列表的创建
和前面我们介绍过的数值(Number )和字符串(str)类似,我们如何创建一个列表?提供三种方法:
[1] >>>> 列表的标准创建格式:
只要把 逗号分隔的不同的数据元素(有序) 使用 方括号(“[]”)括起来就可以完成一个列表的定义,如下:
1 | 'Michael', 'Bob', 'Tracy'] classmates = [ |
但请注意,列表中的数据元素可以具有不同的数据类型(支持数字、字符串,甚至可以包含列表(所谓的列表嵌套),以及后续将要学习的元组、字典、集合等):
1 | >>> list1 = ['string test', 123.321, [1,2], {"name":1,"age":2}, (1,2,"test")] |
注意:在实际使用列表时,虽然可以将不同类型的数据放入到同一个列表中,但通常情况下不这么做,同一列表中只放入同一类型的数据,这样可以提高程序的可读性。
空列表 >>>>
使用此方式创建列表时,列表中元素可以有多个,也可以一个都没有(空列表),例如:
1 | emptylist = [] |
[2] >>>> list(Iterable) 内建函数创建列表:
除了使用 []
创建列表外,Python 还提供了一个内置的函数 list(Iterable)
,使用它可以将其它可迭代对象转换为列表类型。
关于 Python 中可迭代对象的说明请参见博文:Python 中的可迭代对象(Iterable)。
例如:
1 | # 将字符串转换成列表: |
运行结果如下
1 | ['h', 'e', 'l', 'l', 'o'] |
[3] >>>> 推导式方法创建列表:
除此之外,我们还可以使用 推导式方法 创建列表:
1 | for x in "abcdefg"] list2 = [x |
========================================================
实际情况下,第 2,3 中方法使用较多,尤其是通过 range() 函数可以快速初始化一个数字列表。
range() 函数常常和 Python 循环结构、推导式(后续会讲,这里先不涉及)一起使用,几乎能够创建任何需要的数字列表。
列表的删除
对于已经创建的列表,如果不再使用,可以使用 del
关键字将其删除。
实际开发中并不经常使用 del 来删除列表,因为 Python 自带的垃圾回收机制会自动销毁无用的列表,即使开发者不手动删除,Python 也会自动将其回收。
del 关键字的语法格式为:
1 | del listname |
Python 删除列表实例演示:
1 | 1, 45, 8, 34] intlist = [ |
序列支持的操作
由于列表(List)属于 Python 的内建序列,故序列(seq)中包含的基本操作 List 也具有。例如:1.索引、2.切片、3.加、4.乘、5.成员检查、6.获取序列的长度、7.取序列中的最大、最小值。
列表索引和切片
[1] >>>> 访问单个列表元素
列表中,可以用索引来访问 list
中每一个对应位置的元素。索引是从 0
开始的(-1
为从末尾的开始位置的逆向索引):
1 | 'Michael', 'Bob', 'Tracy'] classmates = [ |
对于嵌套列表元素的特殊索引:
1 | 'str1', 'str2', ['list_element1', 'list_element2']] list1 = [ |
注意,当索引超出了 list
范围时,Python 会报一个 IndexError
错误,所以,要确保索引不要越界(超出列表的容量)。
1 | 3] classmates[ |
[2] >>>> 切片
与字符串的分割(切片)一样,我们可以通过[]
和 :
对列表进行切片操作,以获得列表中的多个元素对象:
1 | 5,6,7,8,9] list1 = [ |
和字符串一样,我们甚至可以指定切片的步长(不常用):
1 | 'Michael', 'Bob', 'Tracy'] classmates = [ |
列表拼接(+)和重复(*)
1 | 1.0, 'welcome'] list1 = [ |
成员检查
可用于判断数据元素(数据项)是否存在于列表中:
1 | 1.0, 'welcome'] list1 = [ |
获取序列长度
len(list)
方法可返回列表元素(数据项)对象个数,也称为列表的长度或容量。
1 | 1, 2.0, "welcome", [1, 2, 3]] list1 = [ |
max(list) && min(list)
max(list)
方法用于返回列表元素中的最大值,min(list)
方法用于返回列表元素中的最小值。
1 | >>> list1, list2 = ['Google', 'Baidu', '360'], [12, 100, 200] |
注意,在获取列表最大或最小值时,必须保证列表元素对象类型一致。
1 | 'Google', 'Baidu', '360'], [12, 100, "200"] list1, list2 = [ |
列表类型转换
前面,我们使用 list(Iterable)
内建函数来创建列表,使用它可以将其它可迭代对象转换为列表类型:
1 | 123.321, 'Google', 'Baidu', '360') aTuple = ( |
列表常用操作整理
由于列表是一个可变的序列对象,实际开发中,经常需要对 Python 列表进行查找和更新操作,包括向列表中添加元素、修改表中元素、删除元素以及进行元素查找。
列表添加元素
[1] >>>> 加法(列表连接)
+
运算符可以将多个(同类型)序列连接起来,对于列表而言,相当于在第一个列表的末尾添加了另一个列表生成一个新的列表,原有的列表不会被改变:
1 | >> language = ["Python", "C++", "Java"] |
注意:
+
更多的是用来拼接列表,而且执行效率并不高,如果想在列表中插入元素,应该使用下面几个专门的方法。
[2] >>>> append(列表追加)
append()
方法用于在列表的末尾追加一个新元素对象,该方法的语法格式如下:
1 | listname.append(obj) |
注意,obj
表示到添加到列表末尾的数据,它可以是单个元素,也可以是列表、元组、集合、字典等。
1 | list = ['Google', 'Baidu', '360', "Google"] |
为什么要强调单个元素 >>>>
1 | 1,2] list1 = [ |
可以看到,当追加元素对象为列表、元组时,会将它们视为一个整体,作为一个元素添加到列表中,从而形成包含列表和元组的新列表。
[3] >>>> extend(列表扩展)
extend(iterable) 和 append(obj) 的不同之处在于:extend(iterable)
不会把可迭代对象视为一个整体,而是把它们包含的元素逐个从列表末尾添加到列表中。
这里 iterable
可以是字符串、列表、元组、集合、字典等。若为字典,则仅会将键(key)作为元素依次添加至原列表的末尾。
1 | 'Google', 'Baidu', '360'] list1 = [ |
| >>>> =============================================================
深入理解列表中的 +
、extend()
、append()
>>>>
+ 可以生成一个新的列表,而 extend(iterable) 和 append(obj) 是在原列表的基础上操作的,不会生成新的列表,无返回值(None)。
1 | # 定义一个包含多个类型的 list |
输出结果为:
1 | [1, 4, 3.4, 'yes', [1, 2]] 140201757210184 |
可以看到,+
可以生成一个新列表,而 extend()
、append()
是没有返回值(NoneType),所以千万不能放在等式的右侧(无意义),这是编程时常犯的错误,一定要引起注意!!!
============================================================= <<<< |
[4] >>>> insert(插入元素)
前面提到的,append() 和 extend() 方法只能在列表末尾插入元素,如果希望在列表中间某个位置插入元素,可以使用 insert(index, obj) 方法(插入的是元素对象):
1 | listname.insert(index , obj) |
其中,index
表示指定位置的索引值。insert() 会将 obj
元素对象插入到 listname
列表第 index
个元素的位置(相当于其它元素对象后移)。
1 | >> list4 = ['Python', 'C++', 'Java'] |
当插入列表或者元祖时,insert() 也会将它们视为一个整体,作为一个元素插入到列表中,这一点和 append() 是一样的。
1 | >> list4.insert(2, ['C#', 'JavaScript']) |
注意,和 extend()、append() 方法一样,insert() 也是没有返回值(NoneType),所以不要放在等式的右侧(无意义)。如果希望在列表的末尾追加元素,更建议使用 append() 和 extend()(insert() 不高效,)。
列表删除元素
Python 列表中删除元素主要分为以下 3 种场景:
- 根据目标 元素所在位置的索引 进行删除,可以使用 del 关键字或者 pop() 方法;
- 根据 元素本身的值 进行删除,可使用列表(list类型)提供的 remove() 方法;
- 将列表中 所有元素全部删除,可使用列表(list类型)提供的 clear() 方法。
[1] >>>>> 根据元素索引删除元素
1)–> del
del 可以删除列表中的单个元素,格式为:
1 | del listname[index] |
例如:
1 | lang = ["Python", "C++", "Java", "PHP", "Ruby", "MATLAB"] |
del 也可以删除中间一段连续的元素,格式为:
1 | del listname[start : end] |
其中,start 表示起始索引,end 表示结束索引。del 会删除从索引 start 到 end 之间的元素,不包括 end 位置的元素(前闭后开)。
例如:
1 | lang = ["Python", "C++", "Java", "PHP", "Ruby", "MATLAB"] |
| >>>> =============================================================
深入理解列表中的 del
>>>>
一定要搞清楚 –> 删除的到底是变量还是数据?:
1 | >> #定义一个包含多个类型的 list |
另外,在实际过程中,即便使用 del
关键字删除了指定变量,且该变量所占用的内存再没有其他变量使用,此内存空间也不会真正地被系统回收并进行二次使用,它只是会被标记为无效内存。
如果想让系统回收这些可用的内存,需要借助 GC
库中的 collect()
函数。例如:
1 | >> import gc |
Python 中具有缓存重用机制,系统为了提升性能,会将一部分变量驻留在内存中。这个机制对于,多线程并发时程序产生大量占用内存的变量无法得到释放,或者某些不再需要使用的全局变量占用着大的内存,导致后续运行中出现内存不足的情况,此时就可以使用 del 关键字来回收内存,使系统的性能得以提升。同时,它可以为团队省去扩充大量内存的成本。
============================================================= >>>> |
2)–> pop([index=-1])
Python pop(index) 方法用来删除列表中指定索引处的元素,具体格式如下:
1 | listname.pop(index=-1) |
其中,如果指定 index
参数,默认会删除列表中的最后一个元素,类似于数据结构中的 “出栈” 操作。
用法举例:
1 | >> list1 = ['Google', 'Baidu', '360'] |
pop() 函数有返回值,意味着 “出栈” 元素是可获取。
大部分编程语言都会提供和 pop() 相对应的方法,就是 push(),该方法用来将元素添加到列表的尾部,类似于数据结构中的“入栈”操作。但是 Python 是个例外,Python 并没有提供 push() 方法,因为完全可以使用 append() 来代替 push() 的功能。
[2] >>>>> 根据元素值删除元素
remove(obj) 函数可用于移除列表中某个值的第一个匹配项。而且必须保证该元素是存在的,否则会引发 ValueError
错误。
1 | >> list1 = ['Google', 'Baidu', '360', "Google"] |
remove(obj) 函数无返回值,可用来进行列表元素对象过滤。
[3] >>>>> 删除列表所有元素
clear() 函数可用于删除列表的所有元素(清空列表),类似于 **del a[:]**。
1 | >> list = ['Google', 'Baidu', '360'] |
列表修改元素
Python 提供了两种修改列表(list)元素的方法,你可以每次修改单个元素,也可以每次修改一组元素(多个)。
[1] >>>>> 修改单个元素
修改单个元素非常简单,直接对元素进行赋值即可:
1 | list = ['Google', 'Baidu', '360', 999] |
[2] >>>>> 修改一组元素
Python 支持通过切片(slice)语法给一组元素赋值,并且是一组值(单个值会报错)。
1 | nums = [40, 36, 89, 2, 36, 100, 7] |
如果对空切片(slice)赋值,就相当于插入一组新的元素:
1 | nums = [40, 36, 89, 2, 36, 100, 7] |
注意,如果不指定步长(step 参数),Python 就不要求新赋值的元素个数与原来的元素个数相同;这意味,该操作既可以为列表添加元素,也可以为列表删除元素。
1 | >> nums = [40, 36, 89, 2, 36, 100, 7] |
列表查找元素
Python 列表(list)提供了 index() 和 count() 方法,它们都可以用来查找元素。
[1] >>>>> 元素数目查询
count() 方法用来统计某个元素在列表中出现的次数,基本语法格式为:
1 | listname.count(obj) |
其中,obj
表示要统计的元素对象。如果 count() 返回 0
,就表示列表中不存在该元素,所以 count() 也可以用来判断列表中的某个元素是否存在。
1 | >> nums = [40, 36, 89, 2, 36, 100, 7, -20.5, 36] |
[2] >>>>> 元素索引查询
list.index() 函数可以用于从列表中找出某个值第一个匹配项的索引位置,如果没有找到对象则抛出异常。所以在查找之前最好使用 count() 方法或者 in
&& not in
判断一下是否存在。
index() 的语法格式为:
1 | listname.index(obj, start, end) |
其中,obj
表示要查找的元素,并且你可以限定查找范围:start 表示起始位置,end 表示结束位置。
1 | list = ['Google', 'Baidu', '360'] |
其它常用操作
[1] >>>>> list.reverse()
reverse(list) 函数用于反向列表中元素。没有返回值,但是会对列表的元素进行反向排序。
1 | list = ['Google', 'Baidu', '360'] |
这里还可以使用序列中的内置函数 reversed(seq)
,其功能是对于给定的序列(包括列表、元组、字符串以及 range(n) 区间),该函数可以返回一个逆序序列的迭代器(用于遍历该逆序序列)。
反向遍历列表的方法(不影响原列表) >>>>
1 | list1 = [1, 2, 3, 4] |
但还是尽量使用迭代器吧,数据量很大的时候不用迭代器的话有可能会占用过多的内存。
[2] >>>>> list.sort( key=None, reverse=False)
sort() 函数用于对原列表进行排序。该方法没有返回值,但是会对列表的对象进行排序。参数说明:
key
:指定用来进行比较的元素。取自于可迭代对象中,指定可迭代对象中的哪一个元素来进行排序。reverse
:定义排序规则,reverse = True 降序, reverse = False 升序(默认)。
1 | list = [1, 2, 3, 4] |
[3] >>>>> list.copy()
copy()
函数用于复制列表(深、浅拷贝混合),返回复制后的新列表。
1 | 'Google', (1,2), [1, 2]] list1 = [ |
Python 中栈和队列的实现
我们知道,队列(Queue [kju])和栈(Stack)是两种数据结构,其内部都是按照固定顺序来存放变量的,二者的区别在于对数据的存、取顺序:
- 队列是,先存入的数据最先取出,即“先进先出”;
- 栈是,最后存入的数据最先取出,即“后进先出”。
List 实现栈和队列
Python 中list 类型数据本身的存放就是有顺序的,而且内部元素又可以是各不相同的类型,非常适合用于队列和栈的实现。
[1] >>>> List 实现队列
使用 list 列表模拟队列功能的实现方法是:定义一个 list 变量,存入数据时使用 insert() 方法,设置其第一个参数为 0
,即表示每次都从最前面插入数据;读取数据时,使用 pop() 方法,即将队列的最后一个元素弹出。
如此 list 列表中数据的存取顺序就符合 “先进先出” 的特点。实现代码如下:
1 | # 定义一个空列表,当做队列 |
[2] >>>> List 实现栈
使用 list 列表模拟栈功能的实现方法是,使用 append() 方法存入数据;使用 pop() 方法读取数据。
如此 list 列表中数据的存取顺序就符合“先进先出”的特点。实现代码如下:
1 | # 定义一个空 list 当做栈 |
collections 实现栈和队列
List 中实现队列的方法中,插入数据的部分是通过 insert()
方法实现的,这种方法效率并不高,因为每次从列表的开头插入一个数据,列表中所有元素都得向后移动一个位置。
一个相对更高效的方法,即使用标准库的 collections 模块中的 deque(double-end queue) 结构体,它被设计成在两端存入和读取都很快的特殊 list,可以用来实现栈和队列的功能。
举个例子:
1 | queueAndStack = deque() |
元组(Tuple)
元组与列表是非常类似的(序列),区别在于元组的元素值不能修改(不可变数据类型),元组是放在括号中,列表是放于方括号中。
元组的创建
Python 提供了两种创建元组的方法:
[1] >>>> 元组的标准创建格式:
元组创建也很简单,只需要在小括号中添加元素(数据项),并使用逗号隔开即可:
1 | 'Google', 'Baidu', '360') tup1 = ( |
注意,当元组中 只包含一个元素 时,需要在元素后面添加逗号,否则括号会被当作运算符使用:
1 | >>>tup1 = (50) |
同理,元组中的元素类型也可以是不同的数据类型(数字类型、字符串、元组、列表、字典等):
1 | 'tuple test', 123.321, [1,2], {"name":1,"age":2}, (1,2,"test")) tuple1 = ( |
不规范写法 >>>>
Python 中,元组通常都是使用一对小括号将所有元素包围起来的,但小括号不是必须的,只要将各元素用逗号隔开,Python 就会将其视为元组:
1 | >> tup1 = '123', '456' |
空元组 >>>>
1 | >>> tup1 = () |
[2] >>>> tuple(Iterable) 内建函数创建列表:
除了使用 () 创建列表外,Python 还提供了一个内置的函数 tuple(Iterable),使用它可以将其它可迭代对象转换为元组类型。
关于 Python 中可迭代对象的说明请参见博文:Python 中的可迭代对象(Iterable)。
使用示例:
1 | # 将字符串转换成元组 |
运行结果如下:
1 | ('h', 'e', 'l', 'l', 'o') |
序列支持的操作
由于元组(tuple)属于 Python 的内建序列,故序列(seq)中包含的基本操作 tuple也具有。例如:1.索引、2.切片、3.加、4.乘、5.成员检查、6.获取序列的长度、7.取序列中的最大、最小值等。
–> 字符串和元组
相较于列表,字符串(str)可执行操作要更接近于元组(tuple),这是由于两者都是属于不可变数据类型导致。但是我们要注意,尽管 tuple 元素不可改变,但它可以包含可变对象,比如列表、字典等。
Python 中的元组是一个不可变对象,所以所有修改和生成元组的操作的实现方法,都是在另一个内存片段中生成一个新字符串对象。
元组索引和切片
[1] >>>> 访问单个元组元素
类似于列表,元组中,可以用索引来访问 list 中每一个对应位置的元素。索引是从 0 开始的(-1 为从末尾的开始位置的逆向索引):
1 | 'Google', 'Baidu', '360') website = ( |
对于嵌套元组索引:
1 | 'str1', 'str2', ['list_element1', 'list_element2']) tup1 = ( |
注意,当索引超出了 tuple
范围时,Python 会报一个IndexError
错误,所以,要确保索引不要越界。
1 | 3] website[ |
[2] >>>> 切片
与列表的分割(切片)一样,我们同样可以通过[]
和 :
对元组进行切片操作:
1 | 'Google', 'Baidu', '360') website = ( |
和字符串一样,我们甚至可以指定切片的步长:
1 | 'Google', 'Baidu', '360') website = ( |
元组拼接(+)和重复(*)
1 | 1.0, 'welcome') tup1 = ( |
成员检查
可用于判断数据元素(数据项)是否存在于列表中:
1 | 1.0, 'welcome') tup1 = ( |
获取序列长度
len(tuple)
方法可返回元组元素(数据项)个数,也称为元组的长度或容量。
1 | 'Google', 'Baidu', '360') tup1 = ( |
max(tuple) && min(tuple)
max(tuple)
方法用于返回元组元素中的最大值,min(tuple)
方法用于返回元组元素中的最小值。
1 | 'Google', 'Baidu', '360'), (12, 100, 200) tup1, tup2 = ( |
注意,在获取元组最大或最小值时,必须保证元组元素类型一致。
1 | 'Google', 'Baidu', '360'), (12, 100, '200') tup1, tup2 = ( |
元组类型转换
前面,我们使用 tuple(Iterable) 内建函数来创建列表,使用它可以将其它可迭代对象转换为列表类型:
1 | 123.321, 'Google', 'Baidu', '360'] list1 = [ |
元组的更新与删除
正如我们之前说的,和列表不同的是,tuple 是不可变数据类型,其元素值是不允许修改的。
所以,和字符串中一样,修改元组元素操作是非法的:
1 | 'Google', 'Baidu', '360') website = ( |
同理,元组中的元素值是不允许删除的,但我们可以使用 del
语句来删除整个元组(引用):
1 | 'Google', 'Baidu', '360') website = ( |
“可变的” tuple ??? >>>>
但是我们要注意:尽管 tuple 元素不可改变,但它可以包含可变对象,比如 list、set、dict等。
先来给出一个样例:
1 | 'a', 'b', ['A', 'B']) tup1 = ( |
哎?之前不是说 tuple
一旦定义后就不可变了吗?怎么后来又变了?
表面上看,tuple
的元素确实变了,但其实变的不是 tuple
的元素,而是 list
的元素。tuple 一开始指向的 list 并没有改成别的 list。所以,tuple 所谓的“不变”是说,tuple 的每个元素,指向永远不变。即指向'a'
,就不能改成指向'b'
,指向一个 list,就不能改成指向其他对象,但指向的这个 list 本身是可变的!!!
深入了解 List && Tuple
这一小节内容可以解释为什么我们会将 List 和 Tuple 放在一篇博文里面阐述。
元组和列表同属序列类型,且都可以按照特定顺序存放一组数据,数据类型不受限制,只要是 Python 支持的数据类型就可以。
元组和列表最大的区别就是 >>>> 元组是一个不可变对象,而列表是一个可变对象
你可以理解为:tuple 元组是一个只读版本的 list 列表。
需要注意的是,这样的差异势必会反应到两者的存储方式上:
[1] >>>> List
先研究一下 Python 中 List 的结构:
1 | typedef struct { |
list 本质上是一个长度可变的连续数组。其中 ob_item
是一个指针列表,里边的每一个指针都指向列表中的元素(前面我们也提到过,索引指向的是相应对象元素的内存空间,或着说,它对应了元素对象的引用),而 allocated
则用于存储该列表目前已被分配的空间大小。
需要注意的是,allocated
和列表的实际空间大小不同,列表实际空间大小,指的是 len(list)
返回的结果,也就是上边代码中注释中的 ob_size
,表示该列表总共存储了多少个元素。而在实际情况中,为了优化存储结构,避免每次增加元素都要重新分配内存,列表预分配的空间 allocated 往往会大于 ob_size。
因此 allocated 和 ob_size 的关系是:allocated >= len(list) = ob_size >= 0
。
如果当前列表分配的空间已满(即 allocated == len(list)
),则会向系统请求更大的内存空间,并把原来的元素全部拷贝过去。
对于 tuple,它是不可变的,意味着元组长度大小固定,且存储元素不可变,所以存储空间也是固定的。
[2] >>>> Tuple
再来看看 Python 中 tuple 的结构:
1 | typedef struct { |
tuple 和 list 相似,本质也是一个数组,但是空间大小固定。
读者可能会问题,既然列表这么强大,还要元组这种序列类型干什么?!!
对比列表和元组存储方式的差异,可以引申出这样的结论,即元组要比列表更加轻量级,轻量级就意味着性能速度的提升。
我们知道,Python 会在后台,对静态数据做一些资源缓存(传送门)。通常来说,因为垃圾回收机制的存在,如果一些变量不被使用了,Python 就会回收它们所占用的内存,返还给操作系统,以便其他变量或其他应用使用。
但是对于一些静态变量(比如元组),如果它不被使用并且占用空间不大时,Python 会暂时缓存这部分内存。这样的话,当下次再创建同样大小的元组时,Python 就可以不用再向操作系统发出请求去寻找内存,而是可以直接分配之前缓存的内存空间,这样就能大大加快程序的运行速度。
[3] >>>> Tuple VS List
计算初始化一个相同元素的列表和元组分别所需的时间。我们可以看到,元组的初始化速度要比列表快 5 倍:
1 | C:\Users\xxxxxx>python -m timeit 'x=(1,2,3,4,5,6)' |
当然,如果你想要增加、删减或者改变元素,那么列表显然更优。因为对于元组来说,必须得通过新建一个元组来完成。
元组确实没有列表那么多功能,但是元组依旧是很重要的序列类型之一,元组的不可替代性体现在以下这些场景中:
- 元组作为很多内置函数和序列类型方法的返回值存在,也就是说,在使用某些函数或者方法时,它的返回值会元组类型,因此你必须对元组进行处理;
- 元组比列表的访问和处理速度更快,因此,当需要对指定元素进行访问,且不涉及修改元素的操作时,建议使用元组;
- 元组可以在映射(和集合的成员)中当做“键”使用,而列表不行。
可变和不可变对象
前面我们一直在说,元组(tuple)和列表(list)很相似,但元组是可变的,列表不可变。
关于 Python 中的可变和不可不对象内容解读参见:Python 中的可变对象和不可变对象。
当然,如果不理解的话,可以暂时将其当成一个黑箱子,学过集合和字典后再来看会更加顺利。
Python 数据结构之 List and Tuple
https://www.orangeshare.cn/2018/01/06/python-shu-ju-jie-gou-zhi-list-and-tuple/
install_url
to use ShareThis. Please set it in _config.yml
.