#%% 列表List
= [1, 2, 3, 4, 5, 6]
numbers = ["a", "b", "c", "d"]
letters print(numbers)
print(letters)
[1, 2, 3, 4, 5, 6]
['a', 'b', 'c', 'd']
在上一章,我们学习了Python的基本“词汇”——单个的数字、文本(字符串)和逻辑值(布尔型)。然而,在现实世界的数据处理中,我们很少只跟单个数据打交道。我们常常需要处理一整个班级的学生名单、一张购物小票上的所有商品、或者一个用户的所有个人信息。
为了有效地组织和管理这些集合数据,Python提供了几种内置的数据结构。它们就像是不同类型的“容器”,可以把多个数据项(元素)按照特定的方式存放起来。
本章我们将探索Python中最常用的四种基本数据结构:
学完本章,你将能够:
掌握这些基本数据结构是进行任何稍复杂的数据处理和分析任务的基础。它们是你未来学习更高级数据分析库(如Pandas)的重要基石。
一个列表List,就是把几个元素(items),用一个固定的顺序连在一起的数据结构。列表List是一个重点,超级常用,内容比较多。
创建一个列表,可以用中括号[]
,其中每一个元素用逗号分开。
为了好看,建议每个逗号后加一个空格。
#%% 列表List
= [1, 2, 3, 4, 5, 6]
numbers = ["a", "b", "c", "d"]
letters print(numbers)
print(letters)
[1, 2, 3, 4, 5, 6]
['a', 'b', 'c', 'd']
列表中的元素,可以混合多种类型。 但一般不建议这么做。
= [1, 2, 3, "a", "b", "c"]
a_list print(a_list)
[1, 2, 3, 'a', 'b', 'c']
也可以+
拼接两个List来创建新的List
= [1,2,3] + [7,8,9]
a_new_list print(a_new_list)
[1, 2, 3, 7, 8, 9]
我们还可以创建空List。比如,当列表的第一个元素还没确定,而你要先行创建列表,然后再生成元素添加进去。
#%% 空列表
= []
empty_list = list()
empty_list print(empty_list)
[]
对一个字符串String 使用list()函数,可以把字符串分解成字母组成的List。这本质上就是类型转换:用类型的名字做转换函数的名字。
如果把函数名list
看成是一个动词,或者可以解释成:list a string。
#%%
print(list('apple'))
['a', 'p', 'p', 'l', 'e']
注意:实际上,list()可以用于所有类型的序列(有序列结构的其他数据),以后我们遇到再说。
特别地,如果我们转换一个多行的字符串,会发现什么?
= '''hello
a python
'''
print(list(a))
['h', 'e', 'l', 'l', 'o', '\n', 'p', 'y', 't', 'h', 'o', 'n', '\n']
注意,换行符\n
也出现在其中。实际上,应该把换行符之类的不可见字符也看成一个真正的字符,实际上存在,但部分情况不可见而已
要引用一个列表的元素,也使用[]
,其中包括元素的索引(index),注意第一个元素的索引是0(Python 和 C 语言一样,从0开始计数)
print(numbers)
print(numbers[0])
print(numbers[3])
[1, 2, 3, 4, 5, 6]
1
4
可以反向引用元素,例如-1
指向最后一个元素,-2
指向倒数第二个,如此类推
print(numbers)
print(numbers[-1])
print(numbers[-2])
[1, 2, 3, 4, 5, 6]
6
5
列表中的元素是可变的。同样,用等号=
对某个元素赋值即可
print(numbers)
0] = 999 # 修改第一个元素的值为999
numbers[print(numbers)
[1, 2, 3, 4, 5, 6]
[999, 2, 3, 4, 5, 6]
添加元素
在List的最后添加元素可以用.append()
。添加多个元素,可以用.extend()
,注意extend
使用一个list作为参数。插入元素到指定索引号.insert()
= list("abcd")
letters print(letters)
'e')# 添加一个元素
letters.append(print(letters)
'f','g']) #添加多个元素:把要添加的元素放进一个list里
letters.extend([print(letters)
3,"apple") #元素插入到指定索引的位置
letters.insert(print(letters)
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd', 'e']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'apple', 'd', 'e', 'f', 'g']
移除:移除某个元素,使用.remove()
;按照索引移除del
print(letters)
'apple') # 如果'apple'不存在,会抛出错误:ValueError: list.remove(x): x not in list
letters.remove(print(letters)
del letters[0]
print(letters)
['a', 'b', 'c', 'apple', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'f', 'g']
['b', 'c', 'd', 'e', 'f', 'g']
题外话:从长度可以知道,最后一个元素的索引号是长度-1
= list("apple")
a print(a)
print(len(a))
['a', 'p', 'p', 'l', 'e']
5
= [1,2,3,4,5]
a print(max(a)) # 如果包含不可比较大小类型,如str,会出错!
print(min(a))
print(sum(a))
5
1
15
.sort()
,默认的排序方式是“从小到大”。与 sorted()
的区别在于:.sort()
原地修改列表,而sorted()
返回一个新的已排序列表。注意:这个方法会改变原List的顺序
= [5,3,4,2,1]
a
a.sort()print(a)
[1, 2, 3, 4, 5]
也可以逆序:从大到小
=True)
a.sort(reverseprint(a)
[5, 4, 3, 2, 1]
sorted()
,注意:sorted()
会返回一个新的、排序后的List,不会改变原List的顺序。
= [5,3,4,2,1]
a print(a)
print(sorted(a)) # 打印排序的结果
print(a) # 原list的顺序并未改变
[5, 3, 4, 2, 1]
[1, 2, 3, 4, 5]
[5, 3, 4, 2, 1]
也可以逆序排序(从大到小)
= [3,4,5,1,2]
b print(sorted(b, reverse=True))
[5, 4, 3, 2, 1]
.count()
= [1,2,2,2,3,3,5,5,5,5,5]
a
print(a.count(3)) # a中的3有多少个?
2
= list('an apple')
a print(a)
print(a.index('p'))
['a', 'n', ' ', 'a', 'p', 'p', 'l', 'e']
4
可以用来回答“是否全班同学都及格?”之类的问题。这部分我们在后面列表推导式会进一步展开。
# 是否全部为真
= [True, True]
a print(all(a))
# 是否有任何一个元素为真
= [False, True]
b print(any(b))
True
True
= [1,2,3,5,6]
a print(3 in a)
print(4 in a)
True
False
pop()
(默认末尾,或指定索引)= [1,2,3,4]
a = a.pop() # 删除末尾,返回 4
last = a.pop(0) # 删除索引0,返回 1
first print(a, last, first)
[2, 3] 4 1
clear()
= [1,2,3]
a
a.clear()print(a)
[]
reverse()
(与切片 a[::-1]
的区别是是否原地)= [1,2,3]
a
a.reverse()print(a)
[3, 2, 1]
key=
与 reverse=
= ['apple','kiwi','banana']
words print(sorted(words, key=len)) # 按长度
print(sorted(words, key=lambda s: s[-1])) # 按最后一个字母
['kiwi', 'apple', 'banana']
['banana', 'apple', 'kiwi']
小思考:如何判断一个元素是否“不在一个列表中”呢?
创建一个名为my_list的列表,包含以下元素:1, 3, 5, 7, 9。然后创建一个变量element,将其赋值为列表中的第四个元素。
创建一个名为my_list的列表,包含以下元素:2, 4, 6, 8。使用append方法将10添加到列表的末尾,然后创建一个变量length,将其赋值为列表的长度。
创建一个名为my_list的列表,包含以下元素:1, 9, 3, 7。使用insert方法在9和3之间插入一个值为5的元素,然后创建一个变量max_value,将其赋值为列表中的最大值。
创建一个名为my_list的列表,包含以下元素:2.2, 3.3, 1.1, 4.4。使用remove方法删除元素1.1,然后创建一个变量min_value,将其赋值为列表中的最小值。
提交范例:
注:不用把题目抄一遍
# Class:你的班级
# Id:你的学号
# Name:你的姓名
# List 练习1
# 练习题1
# <这里写第1题的代码>
# 练习题2
# <这里写第2题的代码>
# 练习题n
# ...
如何获取(或者修改)一个List中的某一段?
= list('abcdef')
a print(a)
['a', 'b', 'c', 'd', 'e', 'f']
截取:从第2个元素开始到第4个元素:(正确答案应该是['b', 'c', 'd']
)
写法是:a[起点 : 终点]
,且得到的结果是“包含起点,但不包含终点”
如: a[1:4]
:切片起止点:包含起点(1号,即b
),不包含终点(不含4号,即e
)
print(a[1:4])
['b', 'c', 'd']
可以不写起点或者终点,默认是到一边的尽头
print(a[:4]) # 4号元素之前(0,1,2,3)(不包含终点)
['a', 'b', 'c', 'd']
print(a[3:]) # 3号元素以及之后(3,4,5)(包含起点)
['d', 'e', 'f']
可以倒数切片:
如从倒数第二个元素开始到最后
print(a[-2:]) # 倒数第二个元素开始到最后(包含起点)
['e', 'f']
从头切到倒数第二个元素(不含终点)
print(a[:-2]) # 从头切到倒数第二个元素(不含终点)
['a', 'b', 'c', 'd']
切片赋值 : 直接覆盖原来的位置的值,可以不等长
= list('abcdef')
a print(a[2:4])
['c', 'd']
注意:a[2:4]
只有2个值,但我们替换成不等长的其他List,如替换3个值进去
2:4] = ['x','y','z']
a[print(a)
['a', 'b', 'x', 'y', 'z', 'e', 'f']
这使得['c', 'd'] -> ['x', 'y', 'z']
赋予空列表,可以达到删除的效果。
2:5] = [] # x,y,z是2,3,4号
a[print(a)
['a', 'b', 'e', 'f']
还可以按步长切片
a[起点:终点:步长]
步长默认为1(每个元素都取值),如果设置为2,每2个元素取一个值
= list('abcdefgh')
a print(f'''a is {a}
a[1:6] is {a[1:6]}
a[1:6:2] is {a[1:6:2]}
''')
a is ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
a[1:6] is ['b', 'c', 'd', 'e', 'f']
a[1:6:2] is ['b', 'd', 'f']
一个简单小技巧:步长也可以取负数,等于逆序取值。因此有一个简单的把列表逆序的方法: [::-1]
= list('apple')
a = a[::-1] # 第一个冒号前后都没有值,表示取整个列表
b print(a)
print(b)
['a', 'p', 'p', 'l', 'e']
['e', 'l', 'p', 'p', 'a']
创建一个名为my_list的列表,包含以下元素:1, 2, 3, 4, 5。使用切片获取前三个元素,并存储在新列表first_three中。
创建一个名为my_list的列表,包含以下元素:1, 2, 3, 4, 5, 6, 7, 8, 9, 10。使用切片和步长来创建一个新列表even_numbers,其中包含my_list中的所有偶数。
创建一个名为my_list的列表,包含以下元素:‘a’, ‘b’, ‘c’, ‘d’, ‘e’。使用切片创建一个新列表reversed_list,它是my_list的一个反转版本。
创建两个列表,名为list1和list2,分别包含以下元素:
使用切片和+操作符创建一个新列表merged_list,它包含list1的前两个元素和list2的后两个元素。
这部分可能有点抽象。
以一个数字来举例
= 123
a print(a)
= a
b print(b)
= 321
a print(f'a is {a}\nb is {b}')
123
123
a is 321
b is 123
中间发生了什么
a = 123
创建了一个整型对象,里面存放了123
,把a
这个名字绑定到这个对象上。
b = a
把a
这个标签,所指代的对象,再贴一个标签b
。这个时候,a
和b
都指向这个整型对象,里面存放了123
。
a = 321
创建了一个新的整型对象,里面存放了321
,把a
这个名字,重新绑定到这个对象上。现在 a -> 321
,b -> 123
但List比较特殊
以letters来举例:
= ["a", "b", "c", "d"]
a print('a is ', a)
a is ['a', 'b', 'c', 'd']
a
指向 ["a", "b", "c", "d"]
= a b
b
指向a
相同的数据["a", "b", "c", "d"]
0] = 'apple'
a[print('b is ', b)
b is ['apple', 'b', 'c', 'd']
a
的值,b
的值也改变了!因为a
和b
一直指向同一个对象。a
复制一次,= ["a", "b", "c", "d"]
a = a.copy()
b print(f'a is {a}\nb is {b}')
a is ['a', 'b', 'c', 'd']
b is ['a', 'b', 'c', 'd']
0] = 'apple' a[
print(f'a is {a}\nb is {b}')
a is ['apple', 'b', 'c', 'd']
b is ['a', 'b', 'c', 'd']
这样就不会互相干扰了。
补充:拷贝列表的常见方式还有切片和构造函数,效果等同于 .copy()
(都是浅拷贝):
= [1,2,3]
a = a[:] # 切片拷贝
b1 = list(a) # 构造函数拷贝
b2 = a.copy() # 方法拷贝
b3 print(b1, b2, b3)
[1, 2, 3] [1, 2, 3] [1, 2, 3]
浅拷贝对嵌套列表并不能复制内层对象(仍然共享):
import copy
= [[1,2],[3,4]]
orig = orig.copy() # 或 orig[:]
shallow = copy.deepcopy(orig)
deep
0][0] = 999
orig[print('orig =', orig)
print('shallow=', shallow) # 受影响
print('deep =', deep) # 不受影响
orig = [[999, 2], [3, 4]]
shallow= [[999, 2], [3, 4]]
deep = [[1, 2], [3, 4]]
总结:
元组:同样是序列结构,可以视为“不可修改的列表”,其中的数据,一旦创建,就不可修改。
和List类似,但使用小括号创建。
注意,从打印的结果也可以看出,()
表示元组,中括号[]
表示列表。
= (1,2,3,4,5)
a print(a) # 元组
= [1,2,3,4,5]
b print(b)
(1, 2, 3, 4, 5)
[1, 2, 3, 4, 5]
如果元组只有1个元素,必须加一个逗号,
,以避免 Python 认为这是个运算。
= (1,) # 正确的做法,识别成元组
a print(a)
= (1)
b print(b) # 会被识别成一个数字
(1,)
1
也可以不用小括号,只使用逗号创建(为了维持代码的清晰和可识别,不建议这么做。)
= 1,2,3,4,5
a print(a)
(1, 2, 3, 4, 5)
访问元组的方法和List完全一样,可以照搬。
但是“可读不可写”,不能做任何修改或删除。
= (1,2,3,4,5) # 读取元素和获得切片等,和List完全一样
a print(a[3])
print(a[2:4])
4
(3, 4)
= (1,2,3,4,5)
a 3] = 999 # 要对元组的值进行修改,会报错 a[
TypeError: 'tuple' object does not support item assignment
List和Tuple用非常接近的结构,互相转换只要用前述的“简单类型转换”方法即可
= list('apple') # str转为list
a_list = tuple(a_list) # list转为tuple
a_tuple print(a_tuple) # 注意,打印的结果是()小括号
('a', 'p', 'p', 'l', 'e')
= (1,2,3,4,5) # 创建一个tuple
a_tuple = list(a_tuple)
a_list print(a_list)
[1, 2, 3, 4, 5]
Tuple只有List的一半能力(只能读,不能改),只用List也可以完成Tuple的所有功能,那用Tuple有何意义?
如前述,List是一个可变类型,可以有不止一个变量名指向同一个List数据。所以,使用List保存的数据,可能会在传递的过程中,在不经意间被你的某些代码所修改,比如忘记.copy()
。
如果一个列表结构的数据,原则上不应该被改变,则可以采用Tuple。如果被代码意外修改,则会报错通知你。
Tuple一般会比List节约内存,但我们一般不必考虑这一点。
Tuple可以用作Dict的Key(后面回说)
因此一般而言,大部分情况下用来作为“数据不应被修改的序列结构”即可。
一个无序的、元素不重复的数据结构。用{}
创建。
= {1,1,2,3,4,4,5} # 创建一个集合
a print(a)
{1, 2, 3, 4, 5}
注意:集合中的元素不会重复。
set()
;{}
表示空字典:print(type({})) # 空字典
print(type(set())) # 空集合
<class 'dict'>
<class 'set'>
a[0]
:= {1, 2, 3}
a 0] a[
TypeError: 'set' object is not subscriptable
这里只简单介绍,后续用到再深入。
.union
或者|
= {1,2,3}
A = {3,4,5}
B
# 并集
print(A.union(B))
print(A|B)
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}
.intersection()
或者&
print(A.intersection(B))
print(A & B)
{3}
{3}
.difference()
或者-
print(A.difference(B))
print(A - B)
{1, 2}
{1, 2}
.symmetric_difference()
或 ^
(属于其中一个集合但不同时属于两个)print(A.symmetric_difference(B))
print(A ^ B)
{1, 2, 4, 5}
{1, 2, 4, 5}
issubset
/ issuperset
print({1,2}.issubset(A))
print(A.issuperset({1,2}))
True
True
in
对 set 为近似 O(1),对 list 为 O(n)。 简单理解:用 in
来检查set,大部分情况下耗时是常数,和set的size无关,但如果用来检查list,则耗时和list的size成正比。一个小技巧:如何去除list中的重复元素?转为set再转回list。注意:转换为Set之后,其中元素的顺序就不保证了。
= list('apple')
a print(a)
= list(set(a))
b print(b) # 顺序不保证和a相同
['a', 'p', 'p', 'l', 'e']
['e', 'a', 'p', 'l']
如果希望“去重且保持原有顺序”,可以使用:
= list('apple')
a print(list(dict.fromkeys(a))) # ['a','p','l','e'],顺序按首次出现
['a', 'p', 'l', 'e']
ids = [101,102,102,103,104,101]
,去重得到唯一客户集合,并判断 105
是否在其中。A = {'a','b','c'}
,B = {'b','c','d'}
,分别求并集、交集、差集、对称差。{1,2}
是否为 {1,2,3}
的子集,并判断 {1,2,3}
是否为 {1,2}
的超集。list(set(seq))
与 list(dict.fromkeys(seq))
,在 seq = list('abcaabbcc')
上分别输出结果并比较顺序。这和新华字典类似:
list(d)[i]
(不推荐在业务逻辑中依赖此方式)。使用大括号,key:value
的方式,key-value之间使用逗号分隔
{key1:value1, key2:value2, ... }
例如班级人数,一班50人,二班49人,三班30人。
这里使用class_x
的字符串来做key,储存班级的人数。这个dict的作用是,可以通过班级的名称来获取班级的人数。
= {'class_1':50, 'class_2':49,'class_3':39}
class_size print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 39}
我们建立了一系列的映射,从字符串(本例中就是班级名称),到键值(本例中是班级人数的整型)
"class_1" -> 50
"class_2" -> 49
"class_3" -> 39
也可以用dict()
函数,同上述例子,但整个写法变成了变量赋值的形式。
= dict(class_1=50,class_2=49,class_3=39)
class_size print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 39}
字典数据的访问,和List或者Tuple一样,都是用中括号[]
,但提供的不是数据的索引index,而是key(键名)
# 获取一班的人数:
# 一班的key是"class_1"
print(class_size['class_1'])
# 当然3班也一样
print(class_size['class_3'])
50
39
修改其值也一样,直接赋值即可
'class_3'] = 40
class_size[print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 40}
实际上,添加键值的方法就是直接赋值
例如,四班,key为class_4,人数为45,则:
'class_4'] = 45
class_size[print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 40, 'class_4': 45}
同样,删除键值的函数是del
,和删除一个变量一样。
删除'class_4'
。
del class_size['class_4']
print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 40}
获得全部的key,使用.keys()
方法。注意是复数,有个s。
print(class_size.keys())
dict_keys(['class_1', 'class_2', 'class_3'])
注意,.keys()
方法返回的不是一个List,所以我们一般还是转为List,便于进行其他操作。转换也是直接采用list()
函数即可。
= list(class_size.keys())
keys print(keys)
['class_1', 'class_2', 'class_3']
获得全部的value,使用.values()
方法。
print(class_size.values()) #同样是复数,有个s。
dict_values([50, 49, 40])
同样,我们可以转换为List。
= list(class_size.values())
values print(values)
[50, 49, 40]
和List一样,dict也可以用len()
函数获得数据的长度
print(len(class_size))
3
= {'a':1, 'b':2}
d 'b':20, 'c':3}) # 合并/更新
d.update({print(d)
= d.pop('a') # 删除并返回指定键
val print(val, d)
= d.popitem() # 弹出并返回“最后插入”的一对
key, val print(key, val, d)
print(d.setdefault('x', 0)) # 若不存在则设置默认值并返回
print(d)
{'a': 1, 'b': 20, 'c': 3}
1 {'b': 20, 'c': 3}
c 3 {'b': 20}
0
{'b': 20, 'x': 0}
= {'apple':3, 'banana':5}
d for k in d: # 遍历键(等同于 d.keys())
print(k)
for k, v in d.items(): # 同时遍历键和值
print(k, v)
print('apple' in d) # 成员测试检查 key 是否存在
apple
banana
apple 3
banana 5
True
= ['A','B','C']
keys = [10, 20, 30]
vals print(dict(zip(keys, vals)))
# 推导式:构造平方表
print({k: v*v for k, v in zip(keys, vals)})
{'A': 10, 'B': 20, 'C': 30}
{'A': 100, 'B': 400, 'C': 900}
和List一样,如果用一个dict为另一个dict赋值,那么2个变量名会指向同一个数据,对其中一个数据的修改,会使得另一个变量中的数据也改变(毕竟只是同一个数据的2个名字)
要避免这一点,同样使用.copy()
函数,拷贝一个dict。具体和List一样,这里不再重复。
如果我们直接读取一个不存在的key,会报错
'class_9'] class_size[
key错误:即找不到’class_9’这key
KeyError: 'class_9'
但是,某些时候,我们想,如果key不存在,则返回一个默认值,而不要因为报错而中断程序。
这个时候可以使用.get()
方法:如果key存在,则返回对应的value。如果不存在,则返回我们前面说过的None
。
print(class_size.get('class_1')) # 获取一个存在的key
print(class_size.get('class_9')) # 获取一个不存在的key
50
None
对于可能不存在的key,我们也可以使用自己指定的值。具体到本例,班级人数不可能是0,所以我们可以考虑用0
来表示这个key(班级名称)不存在,或者你打错字了。
.get()
这个方法的第二个参数,则是找不到key的时候的默认值。
print(class_size.get('class_9', 0))
0
判断一个key是否存在, 也是用in
。
print('class_1' in class_size) # class_1是存在的
print('class_9' in class_size) # class_9是不存在的
True
False
dict也可以视为一个类List的数据结构:其中每一个元素,是一个(键-值)对,即(key, value)
的元组。
= {'class_1':50, 'class_2':49,'class_3':39}
class_size print(class_size)
{'class_1': 50, 'class_2': 49, 'class_3': 39}
可以使用.items()
这个方法,获取一个dict的所有(key, value)
对。
print(class_size.items())
dict_items([('class_1', 50), ('class_2', 49), ('class_3', 39)])
当然,我们也可以转为一个真正的List用list()
函数
= list(class_size.items())
all_items print(all_items)
[('class_1', 50), ('class_2', 49), ('class_3', 39)]
显然,这是3个(key, value)
元组构成的List。
注意
[]
:这是一个List()
:每一个元素是一个Tuple看看第一个元素是什么?
print(all_items[0])
('class_1', 50)
易见,这就是一个(一班的名称, 一班的人数)组成的元组。
'name': 'Alice'
'age': 25
'city': 'New York'
题目2:访问字典中的值 使用刚刚创建的 person_info 字典。编写一个Python语句来访问键 ‘age’ 对应的值,并将其存储在一个名为 age_value 的变量中。
题目3:添加键值对 在 person_info 字典中添加一个新的键值对,其中键为 ‘occupation’,值为 ‘Engineer’。
题目4:修改字典中的值 修改 person_info 字典中键 ‘city’ 对应的值为 ‘San Francisco’。
题目5:删除键值对和获取所有键 首先,删除 person_info 字典中键 ‘age’ 及其对应的值。然后获取该字典中所有的键,并将它们存储在一个名为 keys_list 的列表中。
你现在已经掌握了Python中的几种核心数据结构。
核心要点回顾:
[]
): 有序、可变的序列。支持索引、切片、添加 (append
, extend
, insert
)、删除 (remove
, del
)、排序 (sort
, sorted
) 等多种操作。是Python中最灵活、最常用的数据结构之一。()
): 有序、不可变的序列。一旦创建,内容无法修改。访问方式(索引、切片)与列表类似。适用于存储不应改变的数据,或作为字典的键。{}
): (概念上)无序、元素唯一的集合。主要用于去重和快速成员检查 (in
),支持并集、交集、差集等数学运算。{key: value}
): 存储键值对的集合,现代Python中保持插入顺序。通过唯一的、不可变的键来快速访问、添加、修改或删除值。.get()
方法可安全地获取值。[start:stop:step]
): 强大的序列(列表、元组、字符串)截取工具,记住“包含起点,不含终点”。b = a
) 会让多个变量指向同一个对象,修改一个会影响另一个。需要独立副本时,必须使用 .copy()
方法。0
。len(seq)
,确认最大索引为 len(seq)-1
,或先做空值/边界判断。in
判断或改用 dict.get(key, default)
提供默认值。sort()
)。为其提供 key=
函数或先做类型清洗。list.remove(x)
时 x
不在列表中。先用 if x in lst:
判断或使用更稳妥的逻辑。append
)。确认对象类型,查阅对应类型的有效方法。global/nonlocal
或在引用前先赋值。