Python数据结构详解(三)- 列表与元组

学习一门语言,了解其数据结构是基础。由于Python是动态编程语言,所以在定义变量时并不需要事先指定变量的数据类型,变量的声明和初始化是同时进行的。

Python有如下五大数据结构类型:

1、Number类型

2、字符串类型

3、列表,元组

4、字典

5、集合

下面我们逐一来了解一下~

本篇主要介绍列表与元组,是数据结构类型介绍的第三篇。

前两篇关于Number类型和字符串类型的介绍,可以点这儿

三、列表与元组

之所以将列表与元组放到一起,是因为这两个数据类型很相似,可以将元组理解为只读的列表结构。

1.1 列表

1.1.1 列表的表达方式

列表的元素和数量可以是任意的,可能只有几个元素,也可能有成千上万个元素,每个元素的类型可以是相同的,也可以是不同的,列表中区分元素顺序,也允许包含重复元素。

下面来看下如何定义一个列表

# 纯数字列表
number = [1, 2, 3, 1]
# 纯字符串列表
names = ["peter", "lili", "gates"]
# 混合列表
person = ["peter", 1993, {"age": 30}, True]

1.1.2 列表的基本操作

  • 索引和切片

列表的操作基本都是索引来实现的。

索引编号默认是从0开始的,并且在python中,还支持反向索引,用负数表示:

names = ["peter", "lili", "gates"]

# 输出结果:peter
print(names[0])

# 输出结果:lili
print(names[-2])

# 超出索引范围,会抛出 “list index out of range” 的错误
print(names[3])

切片操作可以从列表中根据指定的开始索引与结束索引来获取一个新的子列表,切片有如下几个特点:

(1)切片截取的是左开右闭区间,s[1:3]取的是s[1]与s[2];

(2)结束索引若为0,会获取一个空列表;

(3)结束索引在列表中的位置若小于等于开始索引在列表中的位置,也会返回一个空列表;

(4)切片默认步长是1,也可以手动指定,但步长不能为0,否则会抛出异常。

str1 = ["h", "e", "l", "l", "o"]

# 输出结果:['h', 'e', 'l', 'l']
print(str1[0:4])
# 结束索引为0,输出结果:[]
print(str1[4:0])
# 输出结果:['l']
print(str1[3:-1])
# 结束索引在列表中的位置小于等于开始索引在列表中的位置,输出结果:(空列表)
print(str1[4:-1])
# 省略开始索引,表示从0开始,输出结果:['h', 'e', 'l', 'l']
print(str1[:4])
# 省略结束索引,表示截取到列表结尾,输出结果:['h', 'e', 'l', 'l', 'o']
print(str1[0:])
# 省略开始与结束索引,表示复制整个列表,输出结果:['h', 'e', 'l', 'l', 'o']
print(str1[:])
# 指定步长为2,输出结果:['h', 'l', 'o']
print(str1[::2])
# 指定反向步长为1,输出结果:['o', 'l', 'l', 'e', 'h']
print(str1[::-1])
  • 列表的加法与乘法

加法操作使用加号(+)完成,表示把加号两端的列表变量连接形成一个新列表;

乘法操作使用星号(*)完成,表示对当前列表对象进行复制并连接,并形成一个新列表。

str1 = ["h", "e", "l", "l", "o"]
str2 = ["w", "o", "r", "l", "d"]
str3 = "hello"
str4 = "world"
# 输出结果:['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
print(str1 + str2)
# 输出结果:['h', 'e', 'l', 'l', 'o', 'h', 'e', 'l', 'l', 'o']
print(str1 * 2)
# 输出结果:helloworld
print(str3 + str4)
# 输出结果:hellohello
print(str3 * 2)

虽然字符串本质上也是列表,但字符串与列表并不能直接相加

str1 = ["h", "e", "l", "l", "o"]
str2 = "hello"
print(str1 + str2)

会抛出异常

  

  • 列表元素的检查( in 运算符)

可以使用 in 运算符检查某个元素是否在列表中,返回True / False

str1 = ["h", "e", "l", "l", "o"]
str2 = "hello"
# 输出结果:True
print('h' in str1)
# 输出结果:True
print('he' in str2)
  • 列表元素的修改与删除

列表元素的修改是通过索引来实现的。

str1 = ["h", "e", "l", "l", "o"]
str1[0] = 'w'
# 替换一个元素,输出结果:['w', 'e', 'l', 'l', 'o']
print(str1)
str1[1:] = [1, 2, 3, 4, 5, 6]
# 使用切片方式替换多个元素,输出结果:['w', 1, 2, 3, 4, 5, 6]
print(str1)

列表的删除很简单,使用 del 语句即可。

str1 = ["h", "e", "l", "l", "o"]
del str1[0]
# 输出结果:['e', 'l', 'l', 'o']
print(str1)
del str1[3:]
# 输出结果:['e', 'l']
print(str1)

1.1.3 多维列表

所谓多维列表,就是列表的元素还是列表,列表的元素还是列表……

呃……还是以二维举例吧~

example = [[1, 2], ["a", "b", "c"], [True, False]]

# 输出结果:['a', 'b', 'c']
print(example[1])

上面是最基本的创建二维列表的方式,但有时候二维列表是根据已有的条件来创建。

i = 3
j = 5
k = [[x**2 for x in range(i)] for y in range(j)]

# 输出结果:[[0, 1, 4], [0, 1, 4], [0, 1, 4], [0, 1, 4], [0, 1, 4]]
print(k)

这边用到了列表解析生成二维列表的方式,现在看不懂没关系,看完下面章节再回头来看这里就明白了。

1.1.4 列表解析

列表解析(或称列表推导)是根据已有列表,高效创建新列表的方式。

列表解析是Python迭代机制的一种应用,常用于创建新的列表。

解析语法:[expr for_var in iterable]

这个语句的核心是 for 循环, 它迭代 iterable 对象的所有条目,前边的 expr 是生成列表元素的表达式。

举个栗子~

array = [x**2 for x in range(1, 5)]
# 输出结果:[1, 4, 9, 16]
print(array)
# 输出结果:[2, 3, 4, 6]
print([x * y for x in range(1, 3) for y in range(2, 4)])

1.2 元组

1.2.1 元组的表达方式

元组与列表一样,也是一种列表,唯一不同的是元组不能修改,将元组理解为只读的列表更容易帮助理解。

下面来看下如何定义一个元组。

number1 = 1, 2, 3, 4
# 输出结果:(1, 2, 3, 4)
print(number1)

number2 = (4, 5, 6, 7)
# 输出结果:(4, 5, 6, 7)
print(number2)

可以看到,元组是用圆括号()括起来的,并且在定义的时候可以不需要加圆括号

也可以将元组分配给多个变量。

x, y, z = (1, 2, 3)
# 输出结果:1 2 3
print(x, y, z)

i, j = 1, 2
# 输出结果:1 2
print(i, j)

利用这个特性,可以很容易的实现变量交换,而无需中间变量。

x, y = 1, 2
x, y = y, x
# 输出结果:2 1
print(x, y)

上面栗子中,变量的数量与元组中的元素数量是相同的,否则会抛出异常。

问题来了,如果元组中元素很多,比如有100个,难道需要定义100个变量么?

其实不用这么麻烦,只需要将部分元素赋给变量,其余元素转化为子列表即可,上栗子~

x, y, *z = (1, 2, 3, 4, 5, 6, 7, 8, 9)
# 输出结果:1 2
print(x, y)
# 输出结果:[3, 4, 5, 6, 7, 8, 9]
print(z)

在上面代码中,右侧的元组有9个元素,而左侧只有3个变量,如果按以前的逻辑,执行这行代码肯定是要抛出异常的,但由于z变量前面有一个 *,这就是通配符,如果放在一个变量前面,表示列表,也就是说,变量z本身就是一个列表

Python解析器首先会按列表中元素的顺序和匹配对应的单个变量,剩下的值都给列表变量,也就是z。所以执行这行代码后,x和y的值分别是1和2,而z的值是[3, 4, 5, 6, 7, 8, 9]。

需要注意的是,左侧变量中只能由一个带 * 的变量,否则python解析器无法确定列表的范围。

x, *y, *z = (1, 2, 3, 4, 5, 6, 7, 8, 9)
print(x, y, z)

 最后,再来看看如何定义只含一个元素的元组。

number1 = 1
# 输出结果:1
print(number1)

number2 = (1)
# 输出结果:1
print(number2)

number3 = 1,
# 输出结果:(1,)
print(number3)

number4 = (1, )
# 输出结果:(1,)
print(number4)

从上面栗子可以看出,定义一个元素的元组需要在末尾加上逗号,否则就只是一个普通的值,并非元组。

1.2.2 元组的基本操作

  • 访问:元组和列表一样,也是通过索引来访问具体的元素;
  • 修改:元组是只读的,不支持元素的修改
  • 删除:元素值不允许删除的,但可使用 del 语句删除整个元组。

1.3 相关函数与方法

1.3.1 列表与元组常用的函数

函数含义
len返回列表/元组中元素数量
max返回列表/元组中最大的元素值(每个元素值必须是可比较的,否则抛异常)
min返回列表/元组中最小的元素值(每个元素值必须是可比较的,否则抛异常)
list元组转换为列表
tuple列表转换为元组
str1 = [1, 2, 3, 4, 5]
# 输出结果:5
print(len(str1))
# 输出结果:5
print(max(str1))
# 输出结果:1
print(min(str1))
str2 = ['h', 'i']
# 这里比较的是字符的ASCII码,输出结果:i
print(max(str2))
# 还记得之前说过,True会被当作 1,输出结果:True
print(max(0, True))

# 会抛异常,这俩之间没法比较
print(max(1, "hello"))

str3 = (1, 2, 3)
# 输出结果:(1, 2, 3)
print(str3)
# 输出结果:[1, 2, 3]
print(list(str3))
# 输出结果:(1, 2, 3)
print(tuple(list(str3)))

1.3.2 列表与元组常用的方法

方法含义
append在列表最后插入新元素
clear清除列表所有内容
copy复制列表/元组
count用于统计某个元素在列表/元组中出现的次数
extend在列表结尾插入另一个列表,即用来扩展原列表
index用于从列表/元组中找出某个值第一次出现的索引位置
insert将某个元素插入列表指定位置
pop移除列表中的元素(默认是最后一个元素),并返回该元素的值
remove移除列表中某个值的第一个匹配元素
reverse列表元素反转
sort列表元素排序
class_one = ["lili", "peter", "gates"]
new_guy = "jack"
class_one.append(new_guy)
# 输出结果:['lili', 'peter', 'gates', 'jack']
print(class_one)
new_guys = ("lili", "lala", "bote")
class_one.extend(new_guys)
# 输出结果:['lili', 'peter', 'gates', 'jack', 'lili', 'lala', 'bote']
print(class_one)

# 拷贝副本
class_two = class_one.copy()
# 指向同一个列表
class_three = class_one
class_one[0] = "lala"

# 修改class_one中的值,class_two不会改变
# 输出结果:['lili', 'peter', 'gates', 'jack', 'lili', 'lala', 'bote'] 
print(class_two)
# 修改class_one中的值,class_three会随着改变
# 输出结果:['lala', 'peter', 'gates', 'jack', 'lili', 'lala', 'bote']
print(class_three)

# 输出结果:2
print(class_two.count("lili"))
# 输出结果:0
print(class_two.index("lili"))
class_one.reverse()
# 输出结果:['bote', 'lala', 'lili', 'jack', 'gates', 'peter', 'lala']
print(class_one)
class_one.sort()
# 输出结果:['bote', 'gates', 'jack', 'lala', 'lala', 'lili', 'peter']
print(class_one)
class_one.clear()
# 输出结果:[]
print(class_one)

1.4 列表与元组的差异

总结一下列表与元组的差异点:

  • 可变性:列表是可变的(Mutable),也就是说,它们的元素可以通过索引进行修改、删除或添加,而元组是不可变的(Immutable),一旦创建就不能被修改。
  • 语法:列表用方括号([])来表示,元素之间用逗号(,)分隔,而元组用圆括号(())来表示,元素之间也用逗号(,)分隔。如果元组只有一个元素,则需要在元素后面加上一个逗号。
  • 使用场景:一般来说,当我们需要在程序中存储一些可以被修改的数据时,应该使用列表。而当我们需要在程序中存储一些不可修改的数据时,应该使用元组。
  • 性能:由于元组是不可变的,因此在一些情况下它们比列表更快,尤其是当元组作为字典的键时。
  • 内存:一般来说,创建元组类型tuple的变量比列表类型list要快,而且占用更小的存储空间。
  • 线程安全:元组类型变量的元素不可更改性,可保证多线程读写时的安全问题。

下篇开始介绍字典,如果觉得小编写的不错的话,麻烦给个关注,点赞、转发~


更多的Python学习资料,可以到这儿获取,持续不间断地免费更新Python资料~

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python数据结构与算法分析是一个专栏,主要记录了如何使用Python学习数据结构与算法的笔记和练习题。这个专栏包括了Python的内置数据结构和扩展数据结构Python给我们提供了很多现成的数据结构类型,如列表元组、字典等,这些是系统预先定义好的数据结构。而还有一些数据组织方式需要我们自己去定义和实现,比如栈、队列等,这些被称为Python的扩展数据结构。通过学习这些数据结构和算法分析,可以更好地理解和应用Python编程语言。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [【Python数据结构与算法】(一)基本概念和算法分析](https://blog.csdn.net/weixin_45052363/article/details/125099029)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [Python 数据结构与算法详解](https://blog.csdn.net/qq_35029061/article/details/127561227)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员树先生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值