云计算百科
云计算领域专业知识百科平台

一文吃透 Python 列表、字典、元组和集合,新手必看!

一、列表(List)

1. 定义与表示
  • 列表是 Python 中最常用的有序、可变数据类型,用于存储一系列元素(元素可以是任意数据类型,包括嵌套列表、字典、集合、元组等)。
  • 表示方式:用 [] 包裹元素,元素之间用逗号分隔,例如:

    list1 = [1, 2, 3] # 整数列表
    list2 = ["a", 1, True, [4, 5]] # 混合类型列表(字符串、布尔、嵌套列表)
    empty_list = [] # 空列表

2. 核心特性
  • 有序性:元素有固定顺序,可通过索引访问(索引从 0 开始)。
  • 可变性:可修改、添加、删除元素(内存地址不变,内容可变)。
  • 可重复性:允许包含重复元素。
  • 异构性:元素可以是不同数据类型(整数、字符串、列表等)。
3. 基本操作
(1)访问元素(索引与切片)
  • 索引:通过 list[index] 访问单个元素(支持正向索引和反向索引)。

    lst = ["a", "b", "c", "d"]
    print(lst[0]) # 正向索引:第1个元素,输出 "a"
    print(lst[-1]) # 反向索引:最后1个元素,输出 "d"

  • 切片:通过 list[start:end:step] 访问子列表(左闭右开,step 为步长)。

    lst = [0, 1, 2, 3, 4, 5]
    print(lst[1:4]) # 从索引1到3,输出 [1, 2, 3]
    print(lst[::2]) # 步长2,取所有偶数索引元素,输出 [0, 2, 4]
    print(lst[::-1]) # 步长-1,反转列表,输出 [5, 4, 3, 2, 1, 0]

(2)修改元素
  • 直接通过索引赋值修改元素:

    lst = [1, 2, 3]
    lst[1] = 20 # 修改索引1的元素,结果:[1, 20, 3]

(3)拼接与重复
  • 拼接:用 + 合并两个列表(生成新列表,原列表不变)。

    lst1 = [1, 2]
    lst2 = [3, 4]
    print(lst1 + lst2) # 输出 [1, 2, 3, 4]

  • 重复:用 * 重复列表元素(生成新列表)。

    lst = [1, 2]
    print(lst * 3) # 输出 [1, 2, 1, 2, 1, 2]

(4)成员判断
  • 用 in 判断元素是否在列表中,not in 判断是否不在。

    lst = [1, 2, 3]
    print(2 in lst) # 输出 True
    print(4 not in lst) # 输出 True

(5)长度、最大 / 最小值
  • len(lst):返回列表元素个数。
  • max(lst)/min(lst):返回列表中最大 / 最小元素(元素需可比较,如全为数字或全为字符串)。

    lst = [3, 1, 4]
    print(len(lst)) # 输出 3
    print(max(lst)) # 输出 4

4. 常用方法(重点)
方法作用示例结果
append(x) 在列表末尾添加元素 x(修改原列表,无返回值) lst = [1,2]; lst.append(3) [1, 2, 3]
extend(iter) 用可迭代对象 iterable(如列表、元组)中的元素扩展到列表(批量添加,原列表不变) lst = [1,2]; lst.extend([3,4]) [1, 2, 3, 4]
insert(index, x) 在索引 index 处插入元素 x(原元素后移) lst = [1,3]; lst.insert(1, 2) [1, 2, 3]
remove(x) 删除列表中第一个出现的元素 x(若不存在则报错) lst = [1,2,2]; lst.remove(2) [1, 2]
pop(index) 删除并返回索引 index 处的元素(默认删除最后一个,索引不存在则报错) lst = [1,2,3]; lst.pop(1) 返回 2,列表变为 [1, 3]
clear() 清空列表(保留空列表) lst = [1,2]; lst.clear() []
index(x) 返回元素 x 在列表中第一个出现的索引(若不存在则报错) lst = [1,2,3,2]; lst.index(2) 返回 1
count(x) 统计元素 x 在列表中出现的次数 lst = [1,2,2,3]; lst.count(2) 返回 2
sort(key=None, reverse=False) 对列表元素排序(默认升序,reverse=True 降序,修改原列表) lst = [3,1,2]; lst.sort() [1, 2, 3]
reverse() 反转列表元素顺序(修改原列表) lst = [1,2,3]; lst.reverse() [3, 2, 1]
copy() 复制列表(浅拷贝,返回新列表) lst = [1,2]; new_lst = lst.copy() new_lst 为 [1,2](与原列表独立)
5. 列表推导式(高效生成列表)
  • 语法:[表达式 for 变量 in 可迭代对象 if 条件]
  • 作用:用一行代码生成列表,比循环更简洁高效。

    # 生成1-10的平方列表
    squares = [x**2 for x in range(1, 11)]
    print(squares) # 输出 [1, 4, 9, …, 100]

    # 筛选偶数
    even_numbers = [x for x in range(1, 11) if x % 2 == 0]
    print(even_numbers) # 输出 [2, 4, 6, 8, 10]

    # 嵌套列表推导式(二维列表转一维)
    matrix = [[1,2], [3,4], [5,6]]
    flat = [num for row in matrix for num in row]
    print(flat) # 输出 [1, 2, 3, 4, 5, 6]

    #嵌套循环(类似双重 for 循环):
    [表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]
    比如 [i*j for i in [1,2] for j in [3,4]] → 结果 [3,4,6,8]

6. 注意事项

注:拷贝的差异,本质上体现在对嵌套的可变对象的处理上。因为对不可变对象来说,不管是深拷贝还是浅拷贝,其实都没啥区别,因为它们本身不能被修改,就相当于复制了一份一样的 “副本”,而且这个 “副本” 和原对象的值、地址啥的都一样。

1. 浅拷贝(shallow copy)

只拷贝 “外层对象”,但对于外层对象中嵌套的可变子对象,不重新创建,而是直接引用原对象的子对象(即共享同一份子对象,同一个地址)。

示例(关键看嵌套的可变对象):

import copy

# 原列表:外层是列表(可变),里面嵌套了一个子列表(可变)
old_list = [1, 2, [3, 4]] # 1、2是不可变对象,[3,4]是可变子对象

# 浅拷贝
new_list = old_list.copy() # 等价于 old_list[:] 或 copy.copy(old_list)

# 测试1:修改外层的不可变元素(不影响原列表)
new_list[0] = 100
print(old_list) # [1, 2, [3, 4]](原列表不变)
print(new_list) # [100, 2, [3, 4]]

# 测试2:修改嵌套的可变子对象(原列表和新列表会同时变化!)
new_list[2][0] = 300 # 修改子列表的第一个元素
print(old_list) # [1, 2, [300, 4]](原列表的子列表被改了!)
print(new_list) # [100, 2, [300, 4]]

2. 深拷贝(deep copy)

不仅拷贝 “外层对象”,还会递归地拷贝所有嵌套的可变子对象,生成完全独立的新对象,与原对象没有任何共享引用。(全部纯纯新的地址)

示例(嵌套对象完全独立):

import copy

old_list = [1, 2, [3, 4]] # 同上

# 深拷贝
new_list = copy.deepcopy(old_list)

# 测试1:修改外层元素(不影响原列表,和浅拷贝一样)
new_list[0] = 100
print(old_list) # [1, 2, [3, 4]]
print(new_list) # [100, 2, [3, 4]]

# 测试2:修改嵌套的可变子对象(原列表完全不受影响!)
new_list[2][0] = 300
print(old_list) # [1, 2, [3, 4]](原列表的子列表没变!)
print(new_list) # [100, 2, [300, 4]]

3.区别
场景浅拷贝(shallow copy)深拷贝(deep copy)
外层对象 复制新对象,独立 复制新对象,独立
嵌套的可变子对象 不复制,共享引用(改一个影响另一个) 递归复制,生成新子对象(完全独立,互不影响)
性能 更快(复制少) 较慢(递归复制多)
  • Python 中的对象分为不可变对象(如整数、字符串、元组)和可变对象(如列表、字典、集合)。

  • 不可变对象:值一旦创建就不能修改,修改时会生成新对象(本质就是生成新地址)。
  • 可变对象:值可以直接修改,修改时不会生成新对象(如 list1[0]=10 是在原地址上改)。
  • 列表切片:new_list = old_list[:]
  • list.copy() 方法:new_list = old_list.copy()
  • copy 模块的 copy() 函数:new_list = copy.copy(old_list)(推荐)
  • copy模块里的copy函数挺万能的,不管是列表、字典还是集合,都能用它来做浅拷贝。这样就不用记每个类型各自的拷贝方法,一个函数搞定好多类型。
  • copy 模块的 deepcopy() 函数:new_list = copy.deepcopy(old_list)
4.应用

浅拷贝:它速度快,占用内存少。如果你的对象里没有嵌套可变对象,或者你不需要对嵌套可变对象进行独立修改,就可以用浅拷贝。比如你只是想复制一个简单的列表,里面都是不可变类型(像整数、字符串),浅拷贝就够,又快又省资源。

深拷贝:当你需要完全独立的副本,尤其是对象有嵌套可变对象,并且你要修改副本里的嵌套对象,又不想影响原对象的时候,深拷贝就派上用场了。

一句话记住:

  • 浅拷贝:“表面复制”,嵌套的可变对象还是 “一家人”。
  • 深拷贝:“连根复制”,嵌套的可变对象也变成 “两家人”,彻底独立。
  • import copy
    lst = [1, [2, 3]]
    shallow = lst.copy()
    deep = copy.deepcopy(lst)
    lst[1].append(4) # 修改子列表
    print(shallow) # 输出 [1, [2, 3, 4]](浅拷贝受影响)
    print(deep) # 输出 [1, [2, 3]](深拷贝不受影响)

  • 列表是可变对象:作为函数参数时,修改列表会影响外部原列表(传引用),因为传入时共用一个地址,这和浅拷贝与深拷贝不同,请读者区分开。

二、字典(Dictionary)

1. 定义与表示
  • 字典是 Python 中键值对映射的可变数据类型,用于存储关联型数据。
  • 表示方式:用 {} 包裹,元素为 键: 值 对,键与值之间用冒号分隔,键值对之间用逗号分隔。

    dict1 = {"name": "张三", "age": 18, "hobby": ["篮球", "游戏"]} # 普通字典
    empty_dict = {} # 空字典
    dict_from_list = dict([("a", 1), ("b", 2)]) # 用dict()函数从列表生成

2. 核心特性
  • 键值对映射:通过唯一的 “键” 访问对应的 “值”,键是访问的唯一标识。
  • 键的约束:键必须是不可变类型(字符串、数字、元组等),且同一字典中键不可重复(重复会被覆盖)。
  • 值的灵活性:值可以是任意数据类型(包括列表、字典、函数等),无限制。
  • 可变性:支持动态添加、修改、删除键值对(内存地址不变,内容可变)。
  • 有序性:Python 3.7+ 后字典是有序的(按插入顺序保存),之前版本无序。
3. 基本操作
(1)访问值
  • 通过键直接访问:dict[key](键不存在则报错)。

    info = {"city": "北京", "area": 16410}
    print(info["city"]) # 输出 "北京"

  • 通过 get() 方法访问:dict.get(key, default)(键不存在则返回默认值,避免报错)。

    print(info.get("population", "未知")) # 输出 "未知"(键"population"不存在)

(2)修改 / 新增键值对
  • 直接赋值:键存在则修改值,键不存在则新增键值对。

    info["area"] = 16411 # 修改已有键的值
    info["population"] = 2184 # 新增键值对
    print(info) # 输出 {"city": "北京", "area": 16411, "population": 2184}

(3)删除键值对
  • del dict[key]:删除指定键值对(键不存在则报错)。
  • dict.pop(key, default):删除并返回指定键的值(键不存在则返回默认值)。
  • dict.clear():清空字典所有键值对(保留空字典)。

    del info["area"] # 删除"area"键值对
    print(info.pop("city", "无")) # 输出 "北京"(删除并返回值)
    info.clear() # 清空字典,结果:{}

(4)其他基础操作
  • 拼接 / 合并:用 dict.update(other_dict) 合并另一个字典(覆盖重复键,后来者居上)。

    a = {"x": 1, "y": 2}
    b = {"y": 3, "z": 4}
    a.update(b) # a变为 {"x": 1, "y": 3, "z": 4}("y"被覆盖)

  • 成员判断:用 in / not in 判断键是否存在(仅判断键,不判断值)。

    print("x" in a) # 输出 True(判断键"x"是否存在)

  • 长度:len(dict) 返回键值对的数量。

    print(len(a)) # 输出 3

4. 常用方法(重点)
方法作用示例结果
dict.keys() 返回所有键组成的可迭代对象(可转成列表) info = {"name": "张三", "age": 18}
info.keys()
list(info.keys())
dict_keys(['name', 'age'])
['name', 'age']
dict.values() 返回所有值组成的可迭代对象(可转成列表) info = {"name": "张三", "age": 18}
info.values()
list(info.values())
dict_values(['张三', 18])
['张三', 18]
dict.items() 返回所有键值对组成的可迭代对象(每个元素为 (键, 值) 元组) info = {"name": "张三", "age": 18}
info.items()
list(info.items())
dict_items([('name', '张三'), ('age', 18)])
[('name', '张三'), ('age', 18)]
dict.copy() 复制字典(浅拷贝,生成新字典) info = {"name": "张三", "age": 18}
info_copy = info.copy()
info_copy
{'name': '张三', 'age': 18}
dict.setdefault(key, default) 若键不存在则新增(值为 default),存在则返回对应值(不修改原字典) info = {"name": "张三"}
info.setdefault("age", 18)
info
info.setdefault("name", "李四")
info
18
{'name': '张三', 'age': 18}
张三
{'name': '张三', 'age': 18}
5. 字典推导式(高效生成字典)
  • 语法:{键表达式: 值表达式 for 变量 in 可迭代对象 if 条件}
  • 作用:用一行代码生成字典,比循环更简洁。

    # 生成1-5的平方字典
    squares = {x: x**2 for x in range(1, 6)}
    print(squares) # 输出 {1:1, 2:4, 3:9, 4:16, 5:25}

    # 筛选值为偶数的键值对
    even_squares = {k: v for k, v in squares.items() if v % 2 == 0}
    print(even_squares) # 输出 {2:4, 4:16}

6. 注意事项
  • 浅拷贝特性:dict.copy() 或 dict 函数复制的是浅拷贝,若字典中嵌套可变对象(如列表),修改嵌套对象会影响原字典和拷贝字典。
  • 作为函数参数:字典是可变对象,作为参数传入函数时,修改字典会影响外部原字典(同列表的传引用特性)。

三、元组(Tuple)

1. 定义与表示
  • 元组是 Python 中不可变的有序序列,用于存储不可修改的一组数据。
  • 表示方式:用 () 包裹元素,元素之间用逗号分隔。例如:

    tuple1 = (10, "苹果", 3.14) # 普通元组
    single_tuple = (5,) # 单元素元组(必须加逗号,否则视为普通括号)
    empty_tuple = () # 空元组
    tuple_from_list = tuple([1, 2, 3]) # 用tuple()函数从列表生成

2. 核心特性
  • 不可变性:元组创建后,元素的数量、顺序、值不可修改(不能新增、删除、替换元素)。
    • 例外:若元素是可变对象(如列表),可修改可变对象的内部内容(但元组本身的结构不变)。
  • 有序性:元素有固定顺序,可通过索引访问(同列表)。
  • 可重复性:允许包含重复元素。
  • 元素灵活性:可存储任意数据类型(包括列表、字典、元组等)。
3. 基本操作
(1)访问元素(索引与切片)
  • 索引:tuple[index](正向索引从 0 开始,反向索引从 – 1 开始)。

    t = ("a", "b", "c", "d")
    print(t[1]) # 输出 "b"(正向索引)
    print(t[-2]) # 输出 "c"(反向索引)

  • 切片:tuple[start:end:step](左闭右开,返回新元组)。

    print(t[1:3]) # 输出 ("b", "c")
    print(t[::-1]) # 输出 ("d", "c", "b", "a")(反转)

(2)拼接与重复
  • 拼接:tuple1 + tuple2(生成新元组,原元组不变)。

    t1 = (1, 2)
    t2 = (3, 4)
    print(t1 + t2) # 输出 (1, 2, 3, 4)

  • 重复:tuple * n(生成新元组,元素重复 n 次)。

    print(t1 * 3) # 输出 (1, 2, 1, 2, 1, 2)

(3)成员判断
  • 用 in / not in 判断元素是否在元组中。

    print("b" in t) # 输出 True

(4)长度、最大 / 最小值
  • len(tuple):返回元素个数。
  • max(tuple) / min(tuple):返回最大 / 最小元素(元素需可比较)。

    nums = (3, 1, 4)
    print(len(nums)) # 输出 3
    print(max(nums)) # 输出 4

4. 常用方法
方法作用示例结果
tuple.count(value) 统计元素 value 在元组中出现的次数 (1, 2, 2, 3).count(2) 2
tuple.index(value) 返回元素 value 在元组中第一次出现的索引(元素不存在则报错) ("a", "b", "a").index("a") 0
5. 注意事项
  • 不可变性的细节:元组本身不可修改,但如果元素是可变对象(如列表),可修改该元素的内部内容。

    t = (1, [2, 3])
    t[1].append(4) # 修改元组中的列表元素(允许)
    print(t) # 输出 (1, [2, 3, 4])

  • 与列表的区别:元组不可变,适合存储固定数据(如配置项、坐标);列表可变,适合存储动态数据。
  • 作为字典的键:元组是不可变类型,可作为字典的键;列表不可作为字典的键。

四、集合(Set)

1. 定义与表示
  • 集合是 Python 中无序、唯一的可变数据集合,用于存储不重复的元素。
  • 表示方式:用 {} 包裹元素(元素之间用逗号分隔),或用 set() 函数生成。例如:

    set1 = {1, 2, 3, 4} # 普通集合(自动去重)
    empty_set = set() # 空集合(不能用{},{}表示空字典)
    set_from_list = set([1, 2, 2, 3]) # 从列表生成集合(自动去重)→ {1, 2, 3}

2. 核心特性
  • 唯一性:集合中元素不可重复,自动去重(添加重复元素会被忽略)。
  • 无序性:元素没有固定顺序,不能通过索引访问(与列表、元组的核心区别)。
  • 元素约束:元素必须是不可变类型(字符串、数字、元组等),不能包含列表、字典等可变类型。
  • 可变性:支持动态添加、删除元素(内存地址不变,内容可变)。
3. 基本操作
(1)添加元素
  • set.add(value):添加单个元素(元素已存在则忽略)。
  • set.update(iterable):添加可迭代对象(如列表、元组)中的所有元素(自动去重)。

    s = {1, 2, 3}
    s.add(4) # 结果:{1, 2, 3, 4}
    s.update([3, 4, 5]) # 添加列表元素,去重后:{1, 2, 3, 4, 5}

(2)删除元素
  • set.remove(value):删除指定元素(元素不存在则报错)。
  • set.discard(value):删除指定元素(元素不存在则忽略,不报错)。
  • set.pop():随机删除并返回一个元素(空集合调用会报错)。
  • set.clear():清空集合所有元素(保留空集合)。

    s.remove(5) # 结果:{1, 2, 3, 4}
    s.discard(6) # 无变化(6不存在)
    print(s.pop()) # 随机返回一个元素(如1),集合变为 {2, 3, 4}

(3)集合运算(核心功能)
  • 交集:set1 & set2 或 set1.intersection(set2) → 两个集合的共同元素。
  • 并集:set1 | set2 或 set1.union(set2) → 两个集合的所有元素(去重)。
  • 差集:set1 – set2 或 set1.difference(set2) → set1 有而 set2 没有的元素。
  • 对称差集:set1 ^ set2 或 set1.symmetric_difference(set2) → 两个集合中互不相同的元素。

    a = {1, 2, 3}
    b = {2, 3, 4}
    print(a & b) # 交集 → {2, 3}
    print(a | b) # 并集 → {1, 2, 3, 4}
    print(a – b) # 差集 → {1}
    print(a ^ b) # 对称差集 → {1, 4}

(4)其他基础操作
  • 成员判断:in / not in 判断元素是否在集合中(效率远高于列表)。

    print(2 in a) # 输出 True

  • 长度:len(set) 返回元素个数。

    print(len(a)) # 输出 3

4. 常用方法
方法作用示例结果
add() 用于向集合中添加元素。如果元素已存在,则不会重复添加。 thisset = {'a', 'b', 'c'}
thisset.add('d')
print(thisset)
{'a', 'b', 'c', 'd'}
remove() 用于移除集合中的指定元素。如果元素不存在,会引发 KeyError 异常。 thisset = {'a', 'b', 'c'}
thisset.remove('b')
print(thisset)
{'a', 'c'}
discard() 也用于移除集合中的指定元素,但如果元素不存在,不会引发异常。 thisset = {'a', 'b', 'c'}
thisset.discard('d')
print(thisset)
{'a', 'b', 'c'}
clear() 用于清空集合中的所有元素,将集合变为空集。 thisset = {'a', 'b', 'c'}
thisset.clear()
print(thisset)
set()
pop() 用于随机移除并返回集合中的一个元素。如果集合为空,会引发 KeyError 异常。 thisset = {'a', 'b', 'c'}
removed_element = thisset.pop()
print(removed_element)
'a'(每次结果可能不同)…

注:列表和集合里都有 pop 方法,但行为不一样。列表的 pop 方法默认删除并返回最后一个元素。集合的 pop 是随机删除并返回一个元素。字典里没有 pop 方法,不过有个 popitem 方法,它是随机删除并返回一个键值对。 

5. 集合推导式(高效生成集合)
  • 语法:{表达式 for 变量 in 可迭代对象 if 条件}
  • 作用:快速生成集合(自动去重)。

    # 生成1-10的偶数集合
    evens = {x for x in range(1, 11) if x % 2 == 0}
    print(evens) # 输出 {2, 4, 6, 8, 10}

    # 从字符串提取不重复字符
    chars = {c for c in "hello world" if c != " "}
    print(chars) # 输出 {'h', 'e', 'l', 'o', 'w', 'r', 'd'}(去重)

6. 注意事项
  • 无序性导致的不可索引:集合没有固定顺序,不能通过索引(如 s[0])访问元素,只能通过 in 判断是否存在,或遍历元素。
  • 元素必须可哈希:集合的元素必须是不可变类型(可哈希),如整数、字符串、元组等。列表、字典、集合等可变类型不能作为集合元素(会报错)。

    s = {1, "a", (2, 3)} # 合法(元素都是不可变类型)
    s = {[1, 2]} # 报错(列表是可变类型,不可哈希)

  • 集合的 pop() 方法随机删除:set.pop() 没有参数,删除的元素是随机的(因集合无序),不能指定删除某个元素(需用 remove 或 discard)。
  • 与字典的表示冲突:空集合必须用 set() 表示,{} 表示的是空字典,而非空集合。
  • 高效的成员判断:集合的 in 操作时间复杂度为 O(1)(远快于列表的 O(n)),适合需要频繁判断 “元素是否存在” 的场景(如去重、数据筛选)。
  • 浅拷贝特性:用 set.copy() 或 copy.copy() 复制集合时,若集合中包含嵌套的可变对象(如元组内的列表,因元组为不可变对象),浅拷贝会共享这些嵌套对象(但集合本身的元素必须是不可变的,所以这种情况较少见)。

 总结

数据类型是否有序元素是否可重复元素是否可以被可变定义符号示例
列表 有序 可重复 可变 [ ] [1, 2, 3]
元组 有序 可重复 不可变 ( ) (1, 2, 3)
集合 无序 不可重复 可变 { } {1, 2, 3}
字典 无序 键不可重复,值可重复 键不可变,值可变 { } {"name": "Tom", "age": 18}

 

赞(0)
未经允许不得转载:网硕互联帮助中心 » 一文吃透 Python 列表、字典、元组和集合,新手必看!
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!