Python内置四种主要数据容器:列表(list)、元组(tuple)、集合(set)和字典(dict)。它们的核心差异在于是否有序、是否可变、是否允许重复元素,以及底层是否基于哈希表。列表和元组有序,集合无序且元素唯一,字典保存键值对。选择容器时,先看数据是否需要修改、是否需要按位置访问、是否需要去重,以及是否需要用键快速查找。
列表:可变有序,操作最丰富
列表用方括号[]表示,元素逗号分隔,可以存储不同类型,也可以嵌套其他列表。创建方式:- fruits = ['apple', 'banana', 'orange']
- numbers = [1, 2, 3, 4, 5]
- mixed = [1, 'text', True, 3.14]
复制代码 常用操作包括:添加元素用 append()、extend()、insert();删除元素用 remove()、pop()、del;查找用 index()、count();排序用 sort()、sorted();反转用 reverse()。列表适合频繁追加、修改和按索引访问的场景,但按值查找和中间插入、删除通常需要线性时间。
元组:不可变,适合固定数据
元组用圆括号()表示,一旦创建不能修改:- coordinates = (10, 20)
- colors = ('red', 'green', 'blue')
复制代码 不可变性带来三个直接好处:防止意外修改,更安全;内存占用和访问速度通常优于列表;元素若可哈希,元组本身可哈希,能作为字典的键。常见用途是保存配置参数、作为函数返回值返回多个值,以及作为字典键。
集合:去重与集合运算
集合用大括号{}表示,元素无序且不重复:- unique_numbers = {1, 2, 3, 3, 4}
- # 结果为 {1, 2, 3, 4}
复制代码 集合基于哈希表实现,成员检查平均为O(1)。它支持并集 union() 或 |、交集 intersection() 或 &、差集 difference() 或 -、对称差集 symmetric_difference() 或 ^。适合去重、关系判断和快速成员检查,但不适合按索引访问。
字典:键值映射,查找效率高
字典用大括号{}保存键值对:- person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
复制代码 字典的键必须唯一,通过键可以快速访问值,且可动态添加、修改和删除键值对。常用操作:访问值用 dict[key] 或 dict.get(key);添加和修改用 dict[key] = value;删除用 del dict[key] 或 dict.pop(key);遍历用 keys()、values()、items()。字典适合需要按业务键检索、统计、分组和缓存的场景。
容器转换、推导式与嵌套
不同容器之间可以相互转换:- my_list = [1, 2, 3]
- my_tuple = tuple(my_list)
- my_tuple = (1, 2, 3)
- my_list = list(my_tuple)
- my_list = [1, 2, 2, 3]
- my_set = set(my_list)
- my_dict = {'a': 1, 'b': 2}
- keys_list = list(my_dict.keys())
- values_list = list(my_dict.values())
复制代码 推导式可以简化容器创建:- squares = [x**2 for x in range(10)]
- square_dict = {x: x**2 for x in range(5)}
- unique_lengths = {len(word) for word in ['hello', 'world', 'python']}
复制代码 容器还可以嵌套,形成矩阵或员工信息:- matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
- employees = {
- 'Alice': {'age': 25, 'position': 'Developer'},
- 'Bob': {'age': 30, 'position': 'Manager'}
- }
- print(matrix[1][2]) # 输出6
- print(employees['Alice']['position']) # 输出'Developer'
复制代码 嵌套容器访问时要逐层取下标或键,尤其是多层字典,建议先确认中间层是否存在,否则容易触发KeyError。
时间复杂度与内存选择
原文给出的复杂度对比可以整理如下:- 操作 列表 元组 集合 字典
- 索引访问 O(1) O(1) - O(1)
- 追加元素 O(1) - - -
- 插入元素 O(n) - - -
- 删除元素 O(n) - O(1) O(1)
- 成员检查 O(n) O(n) O(1) O(1)
- 遍历 O(n) O(n) O(n) O(n)
复制代码 内存方面,列表需要额外空间应对增长;元组固定大小,最节省内存;集合和字典都基于哈希表,集合占用较大,字典通常占用最大。因此,如果数据不需要修改,元组比列表更合适;如果需要去重或快速判断成员,集合更合适;如果需要按键查找,字典优先。
常见陷阱与处理
浅拷贝只复制外层容器,嵌套对象仍共享引用:- original = [[1, 2], [3, 4]]
- shallow_copy = original.copy()
- shallow_copy[0][0] = 99 # 会影响original
- import copy
- deep_copy = copy.deepcopy(original)
复制代码 需要完全独立副本时使用 copy.deepcopy。字典的键必须是不可变类型,如字符串、数字、元组,列表这类可变类型不能作为键。集合依赖元素的哈希值判断唯一性,自定义对象若要放入集合,需要正确实现 __hash__ 和 __eq__ 方法。
实际应用:分组、两数之和与配置读写
销售数据分组统计是字典和列表的典型组合:- from collections import defaultdict
- region_sales = defaultdict(list)
- for sale in sales:
- region_sales[sale['region']].append(sale)
- product_totals = {}
- for sale in sales:
- product = sale['product']
- product_totals[product] = product_totals.get(product, 0) + sale['amount']
复制代码 两数之和问题利用字典的O(1)查找,把暴力O(n²)降到O(n):- def two_sum(nums, target):
- seen = {}
- for i, num in enumerate(nums):
- complement = target - num
- if complement in seen:
- return [seen[complement], i]
- seen[num] = i
- return []
复制代码 JSON配置文件也可以用字典处理:- import json
- with open('config.json') as f:
- config = json.load(f)
- config['timeout'] = 30
- with open('config.json', 'w') as f:
- json.dump(config, f, indent=4)
复制代码
collections模块与第三方容器
标准库 collections 提供更多专用容器:defaultdict 带默认值,OrderedDict 保持插入顺序,Counter 用于计数,deque 双端队列。示例:- from collections import defaultdict, Counter
- word_counts = defaultdict(int)
- for word in words:
- word_counts[word] += 1
- sales_count = Counter(product['name'] for product in sales_data)
复制代码 特殊需求也可以考虑第三方库:numpy数组用于数值计算,pandas DataFrame用于表格数据处理,blist用于大规模列表的高效替代。
性能优化技巧
预分配列表空间,避免反复扩容:- result = [0] * 10000
- for i in range(10000):
- result[i] = i
复制代码 处理大数据时用生成器表达式惰性计算:- big_list = [x**2 for x in range(1000000)]
- big_gen = (x**2 for x in range(1000000))
复制代码 字典分组可用 setdefault 替代先判断再初始化:- my_dict.setdefault(key, []).append(value)
复制代码 总体来看,Python数据容器的选择不只是语法问题,而是直接影响代码可读性、查找效率和内存占用。列表适合有序可变数据,元组适合固定数据,集合适合去重和集合运算,字典适合键值映射。掌握转换、推导式、嵌套访问、复杂度和深浅拷贝,可以在数据处理、算法和配置管理里写出更稳定的Python脚本。 |