news 2026/10/22 7:25:46

4、Python 内置容器类型:list、tuple、set、dict 详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
4、Python 内置容器类型:list、tuple、set、dict 详解

开篇

在Python编程里,绝大多数业务场景都需要批量存储、处理一组数据。Python内置了四种最核心的容器类型:list(列表)、tuple(元组)、set(集合)、dict(字典)。

很多初学者刚接触时很容易混淆:它们是否有序、能不能修改、元素是否允许重复,以及什么时候该选用哪一种容器。本文结合交互式示例,从定义、常用操作、底层特性、经典坑点逐一讲解,文末附带对比表、练习题与总结,帮你彻底搞懂四大容器。

一句话快速总览:

  • list列表:有序可变,元素允许重复,通用动态数组
  • tuple元组:有序不可变,元素允许重复,适合存放固定数据
  • set集合:无序可变,元素不可重复,主打去重与集合运算
  • dict字典:键值对映射,3.7+保留插入顺序,key不可重复,哈希表高速查找

补充:Python3.7及以上版本字典会保留插入顺序,但本质是哈希映射结构,并非序列。


1. list 列表(动态数组)

1.1 定义与特点

Python内置的一种数据类型是列表:list。list是有序的可变集合,可以随时添加和删除其中的元素。

比如,列出班里所有同学的名字,就可以用一个list表示:

>>> classmates = ['Michael', 'Bob', 'Tracy'] >>> classmates ['Michael', 'Bob', 'Tracy']

变量classmates就是一个list。用len()函数可以获得list元素的个数:

>>> len(classmates) 3

用索引来访问list中每一个位置的元素,索引从0开始:

>>> classmates[0] 'Michael' >>> classmates[1] 'Bob' >>> classmates[2] 'Tracy' >>> classmates[3] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range

当索引超出范围,Python抛出IndexError索引越界。记住:最后一个元素索引 =len(classmates) - 1。

如果要取最后一个元素,可以用-1做索引,直接获取末尾元素:

>>> classmates[-1] 'Tracy'

以此类推,-2倒数第2、-3倒数第3:

>>> classmates[-2] 'Bob' >>> classmates[-3] 'Michael' >>> classmates[-4] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range

倒数第4个索引越界,同样报错。

1.2 常用操作

list是可变有序表,支持增、删、改:

# 在末尾追加元素 append() >>> classmates.append('Adam') >>> classmates ['Michael', 'Bob', 'Tracy', 'Adam'] # 在指定索引位置插入 insert(索引,元素) >>> classmates.insert(1, 'Jack') >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy', 'Adam'] # 删除末尾元素 pop(),返回被删除的值 >>> classmates.pop() 'Adam' >>> classmates ['Michael', 'Jack', 'Bob', 'Tracy'] # 删除指定索引的元素 pop(i) >>> classmates.pop(1) 'Jack' >>> classmates ['Michael', 'Bob', 'Tracy'] # 修改指定索引元素,直接赋值 >>> classmates[1] = 'Sarah' >>> classmates ['Michael', 'Sarah', 'Tracy']

list里面元素数据类型可以混合:

>>> L = ['Apple', 123, True]

list元素还可以是另一个list(嵌套列表,二维数组):

>>> s = ['python', 'java', ['asp', 'php'], 'scheme'] >>> len(s) 4

注意:s一共只有4个元素,s[2]本身又是一个list。拆开写更直观:

>>> p = ['asp', 'php'] >>> s = ['python', 'java', p, 'scheme']

想要拿到php,可以写p[1]或者s[2][1]。理论上可以构造三维、四维数组,但日常开发极少使用。

没有任何元素的list是空列表,长度为0:

>>> L = [] >>> len(L) 0

1.3 优缺点 & 使用场景

优点:灵活,支持增删改查,有序可索引,使用简单 缺点:in成员判断需要遍历,查找速度慢;中间位置插入/删除会移动大量元素,性能差

适用场景:需要保存有序数据、需要频繁增删元素。

⚠️ 经典坑:列表是引用传递,浅拷贝容易踩坑

a = [1,2,3] b = a b.append(4) print(a) # a也被修改,a、b指向同一个列表对象

2. tuple 元组

2.1 定义与特点

另一种有序列表叫元组:tuple。tuple和list非常类似,但是tuple一旦初始化就不能修改。

同样存储同学名字示例:

>>> classmates = ('Michael', 'Bob', 'Tracy')

定义完成后,classmates这个tuple就无法变更。它没有append()、insert()这类增删方法。读取元素方式和list完全一致,支持classmates[0]、classmates[-1],但不能对索引位置重新赋值。

不可变tuple的意义:tuple不可变,代码更安全。如果确定数据不会改动,优先用tuple代替list。

2.2 定义元组的陷阱

定义tuple时,元素在定义阶段就必须确定。

>>> t = (1, 2) >>> t (1, 2)

空元组直接写一对括号():

>>> t = () >>> t ()

⚠️ 重点坑点:单元素元组必须加逗号

>>> t = (1) >>> t 1

上面代码定义的不是元组,只是数字1。因为括号()既可以代表元组,也代表数学小括号,Python优先解释为数学表达式。单元素元组末尾必须添加逗号,,消除歧义:

>>> t = (1,) >>> t (1,)

Python打印单元素元组时,也会自动带上逗号,防止和普通数值混淆。

2.3 “看起来可变”的tuple

>>> t = ('a', 'b', ['A', 'B']) >>> t[2][0] = 'X' >>> t[2][1] = 'Y' >>> t ('a', 'b', ['X', 'Y'])

tuple定义时有3个元素:'a'、'b'、一个list。不是说tuple不可变吗?

核心理解:tuple所谓不可变,指元素的引用指向不可变。 tuple指向'a',就不能改成指向别的对象;指向list,就不能改成指向其他对象。但是list本身是可变对象,list内部元素可以修改!表面上看元组内容变了,但元组存储的引用地址完全没变。

如果想要完全不可变的tuple,必须保证元组内每一个元素本身都是不可变对象。

2.4 优缺点 & 使用场景

优点:不可变,数据安全;可哈希,可作为dict的key;内存占用比list更小

缺点:创建完成后不能修改

使用场景:固定不变的数据、函数多返回值、作为字典key。

配套练习 请用索引取出下面list的指定元素:

L = [ ['Apple', 'Google', 'Microsoft'], ['Java', 'Python', 'Ruby', 'PHP'], ['Adam', 'Bart', 'Bob'] ] # 打印Apple: print(L[0][0]) # 打印Python: print(L[1][1]) # 打印Bob: print(L[2][2])

请问以下变量哪些是tuple类型:

a = () # tuple b = (1) # int c = [2] # list d = (3,) # tuple e = (4,5,6) # tuple

list & tuple小结 list 和 tuple 是Python内置有序集合,list可变,tuple不可变,根据业务需求选择。


3. dict 字典(键值对映射)

3.1 定义与特点

Python内置字典dict,全称dictionary,其他语言常叫map。使用**key-value(键值对)**存储,查找速度极快。

场景举例:根据名字查找成绩。如果用两个list实现:

names = ['Michael', 'Bob', 'Tracy'] scores = [95, 75, 85]

给定名字查成绩,需要遍历names找到下标,再取scores的值,list越长,速度越慢。

用dict只需要一张名字-成绩映射表,无论数据量多大,查找速度几乎不变:

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85} >>> d['Michael'] 95
dict高速查找原理

原理类似查纸质字典:

  • list查找:从头到尾一页一页翻,数据越多越慢
  • dict查找:通过哈希算法直接计算key对应的内存地址,一步定位,速度几乎不受数据量影响

dict是用空间换时间的数据结构。存入数据时,根据key计算存储位置;读取时,同样通过key直接定位value。

3.2 常用操作

# 添加键值对,直接赋值 >>> d['Adam'] = 67 >>> d['Adam'] 67

同一个key多次赋值,后面的值会覆盖旧值:

>>> d['Jack'] = 90 >>> d['Jack'] 90 >>> d['Jack'] = 88 >>> d['Jack'] 88

访问不存在的key,会抛出KeyError:

>>> d['Thomas'] Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'Thomas'

两种方案避免报错:

  1. in判断key是否存在
>>> 'Thomas' in d False
  1. get()方法,key不存在默认返回None,可自定义默认返回值
>>> d.get('Thomas') >>> d.get('Thomas', -1) -1

提示:Python交互环境中,返回None不会显示任何输出。

删除key(连同value一起删除),使用pop(key),返回被删除value:

>>> d.pop('Bob') 75 >>> d {'Michael': 95, 'Tracy': 85}

注意:Python3.7之前字典不保证顺序;Python3.7+字典会保留key插入顺序。

3.3 dict vs list 对比

dict

  • 查找、插入速度极快,性能不随元素数量衰减
  • 内存占用高,空间换时间

list

  • 查找、插入耗时随元素变多而增加
  • 内存占用更小

3.4 重要规则:key必须是不可变对象

dict依靠哈希算法计算key的存储位置。如果key可变,哈希值会变化,哈希表直接失效。 字符串、整数、tuple都是不可变对象,可以作为key;list是可变对象,不能作为dict的key。

>>> key = [1, 2, 3] >>> d[key] = 'a list' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'list'

3.5 优缺点 & 使用场景

优点:按键查找O(1)速度;键值对应关系直观清晰

❌ 缺点:内存开销大;key必须是可哈希(不可变)对象,key不能重复

👉 使用场景:一对一映射关系,用户信息、词频统计、映射查表。


4. set 集合

4.1 定义与特点

set底层原理和dict很像,只存储key,不存储value。由于key不能重复,集合自带自动去重特性。

两种创建方式:

>>> s = {1, 2, 3} >>> s {1, 2, 3} # 传入list构造set >>> s = set([1, 2, 3]) >>> s {1, 2, 3}

注意:打印集合展示的顺序不代表集合有序。

重复元素放入set会自动过滤:

>>> s = {1, 1, 2, 2, 3, 3} >>> s {1, 2, 3}

4.2 常用操作

# add 添加元素,重复添加无效果 >>> s.add(4) >>> s {1, 2, 3, 4} >>> s.add(4) >>> s {1, 2, 3, 4} # remove 删除指定元素 >>> s.remove(4) >>> s {1, 2, 3}

set支持数学集合运算:交集、并集

>>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s1 & s2 # 交集,两个集合共有的元素 {2, 3} >>> s1 | s2 # 并集,两个集合全部元素,自动去重 {1, 2, 3, 4}

set和dict底层原理一致,不能放入可变对象(list/dict),可变对象无法哈希,不能存入集合。

4.3 优缺点 & 使用场景

✅ 优点:自动去重;x in set成员判断速度极快

❌ 缺点:无序,不支持下标索引;元素必须可哈希,不能重复

👉 使用场景:列表去重、求两个数据集的交集差集、快速成员判断。

小提示:list(set(原始列表))可以快速去重;但旧版本Python会丢失顺序,需要保序场景不推荐直接使用。


5. 再议不可变对象

str字符串是不可变对象,list是可变对象。

可变对象list,调用方法会直接修改原对象本身:

>>> a = ['c', 'b', 'a'] >>> a.sort() >>> a ['a', 'b', 'c']

不可变对象字符串,调用方法不会修改原对象,只会返回新对象:

>>> a = 'abc' >>> a.replace('a', 'A') 'Abc' >>> a 'abc'

拆开看更清晰:

>>> a = 'abc' >>> b = a.replace('a', 'A') >>> b 'Abc' >>> a 'abc'

核心理解:变量a只是一个标签,指向内存里的字符串对象'abc'。

┌───┐ ┌───────┐ │ a │────▶│ 'abc' │ └───┘ └───────┘

replace()作用在'abc'字符串对象上,不会修改原字符串,而是生成全新字符串'Abc'返回。变量b指向新对象,a仍然指向原来的字符串。

┌───┐ ┌───────┐ │ a │────▶│ 'abc' │ └───┘ └───────┘ ┌───┐ ┌───────┐ │ b │────▶│ 'Abc' │ └───┘ └───────┘

核心结论:调用不可变对象的方法,永远不会修改原对象,只会返回新对象,保证不可变对象恒定不变。


6. 四大容器对比总表

类型符号是否有序是否可变元素允许重复底层结构核心用途
list[]✅有序✅可变✅允许动态数组顺序存储,频繁增删
tuple()✅有序❌不可变✅允许常量数组固定数据,安全,可哈希
set{}❌无序✅可变❌不允许哈希表去重、集合运算
dict{k:v}3.7+保序✅可变key不可重复哈希表键值映射,高速查找

补充概念:可哈希(hashable):int、str、tuple;不可哈希:list、set、dict。不可哈希对象不能作为set元素,也不能作为dict的key。

7. 综合实战小案例

需求:统计一句话中每个单词出现次数

text = "hello python hello world python python" word_list = text.split() count_dict = {} for word in word_list: if word in count_dict: count_dict[word] += 1 else: count_dict[word] = 1 print(count_dict) # 输出:{'hello': 2, 'python': 3, 'world': 1} # 获取全部不重复单词 unique_words = set(word_list) print(unique_words)

结尾总结

Python四大内置容器是编程基础中的重中之重,选型核心判断逻辑:

  1. 需要有序存储、频繁增删元素 →list
  2. 数据固定,不希望被意外修改,需要可哈希特性 →tuple
  3. 需要自动去重、求交集/并集,快速判断元素是否存在 →set
  4. 需要一对一映射关系,按键高速查找 →dict

容器选型的核心原则:根据数据是否有序、是否允许重复、是否需要映射关系做选择。同时一定要理解可变对象、不可变对象与哈希的概念,这是用好set和dict的关键,也是Python面试高频考点。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/22 7:25:19

高并发登录接口性能测试全解析

功能模块性能测试用例验证 功能模块上线前&#xff0c;性能测试用例是保障系统稳定性的关键环节。本文以高并发接口为例&#xff0c;演示性能测试用例的设计、执行与验证流程。 一、测试目标与场景设计 被测模块&#xff1a;用户登录鉴权接口 /api/login&#xff0c;核心指标如…

作者头像 李华
网站建设 2026/10/22 7:24:24

python杂识--24--Nuitak打包exe

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 7:21:40

【脚本】 【Linux】重命名网卡

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/22 7:19:57

Lightpanda 无头浏览器完整上手指南:1/16 内存跑满 JS 渲染页面

Lightpanda 无头浏览器完整上手指南&#xff1a;1/16 内存跑满 JS 渲染页面 【免费下载链接】browser Lightpanda: the headless browser designed for AI and automation 项目地址: https://gitcode.com/GitHub_Trending/browser32/browser Lightpanda 是一个用 Zig 从…

作者头像 李华