Python数据结构入门:列表、字典与集合的高效用法

小林子
小林子
发布时间:2026-09-18| 8人浏览过
原创

Python 中最常用的三种内置数据结构是列表 list、字典 dict 和集合 set。 它们看起来都能“保存一批数据”,但解决的问题并不相同:列表适合保存有顺序的数据,字典适合通过键快速找到对应值,集合则特别适合去重和成员判断。 真正用好它们,重点不是记住所有方法,而是先判断数据之间是什么关系,再选择合适的结构。

一、先理解列表、字典和集合分别解决什么问题

可以先从三个很常见的需求理解它们。

  • 保存用户最近浏览过的文章,并保持浏览顺序:使用列表。
  • 根据用户名查找用户资料:使用字典。
  • 判断某个标签是否已经存在,或者删除重复标签:使用集合。
SVG 配图 1
图1:列表、字典和集合关注的数据关系不同,这是选择数据结构的第一依据。
数据结构 写法示例 主要特点 典型场景
列表 list ["Python", "PHP", "Java"] 有顺序,可以重复,可按索引访问 步骤、记录、商品列表、文章列表
字典 dict {"name": "Tom", "age": 20} 一个键对应一个值,通过键读取 配置、用户信息、数据映射
集合 set {"Python", "PHP", "Java"} 元素唯一,适合判断成员和集合运算 去重、权限判断、标签比较

二、列表:处理有顺序的一组数据

列表适合处理“第一个、第二个、下一个”这类有顺序关系的数据。 列表中的元素可以重复,也可以随时增加、删除或修改。

1. 创建和读取列表

假设要保存一组正在学习的编程语言:

languages = ["Python", "Java", "PHP"]

print(languages[0])
print(languages[1])
print(languages[-1])

示例输出:

Python
Java
PHP

列表索引从 0 开始,因此 languages[0] 表示第一个元素。 负数索引从末尾开始计算,-1 就是最后一个元素。

2. 添加、修改和删除元素

languages = ["Python", "Java"]

# 在末尾增加一个元素
languages.append("PHP")

# 修改第二个元素
languages[1] = "Go"

# 删除指定元素
languages.remove("PHP")

print(languages)

示例输出:

['Python', 'Go']

append() 是添加单个元素时最常见的写法。 如果需要一次加入多个元素,可以使用 extend():

languages = ["Python", "Java"]
languages.extend(["PHP", "Go"])

print(languages)

示例输出:

['Python', 'Java', 'PHP', 'Go']
注意: append(["PHP", "Go"]) 会把整个列表作为一个元素加入; extend(["PHP", "Go"]) 才会把两个字符串分别加入原列表。

3. 使用列表推导式完成简单转换

当需求是“遍历一个列表,把每个元素按照相同规则转换后组成新列表”时,列表推导式通常比手工创建空列表更加紧凑。

numbers = [1, 2, 3, 4, 5]

squares = [number * number for number in numbers]

print(squares)

示例输出:

[1, 4, 9, 16, 25]

还可以加入条件:

numbers = [1, 2, 3, 4, 5, 6]

even_numbers = [number for number in numbers if number % 2 == 0]

print(even_numbers)

示例输出:

[2, 4, 6]

不过,推导式适合规则比较简单的转换。如果条件很多、嵌套层次较深,普通的 for 循环往往更容易阅读。 “代码更短”并不等于“代码更高效”。

三、字典:通过键快速找到对应的数据

如果数据不是单纯排成一列,而是存在明确的“名称 → 值”关系,字典通常比列表更合适。 例如一个用户包含姓名、年龄和所学语言,这些值都有自己的字段名称。

user = {
    "name": "Tom",
    "age": 20,
    "language": "Python"
}

print(user["name"])
print(user["language"])

示例输出:

Tom
Python

1. 修改和增加键值

user = {
    "name": "Tom",
    "age": 20
}

user["age"] = 21
user["language"] = "Python"

print(user)

示例输出:

{'name': 'Tom', 'age': 21, 'language': 'Python'}

如果键已经存在,赋值会修改原值;如果键不存在,则会创建新的键值对。

2. 读取可能不存在的键时使用 get()

直接读取不存在的键会产生 KeyError:

user = {"name": "Tom"}

print(user["email"])

如果一个字段本来就可能缺失,可以改用 get():

user = {"name": "Tom"}

email = user.get("email", "未填写")
print(email)

示例输出:

未填写

这里第二个参数表示默认值。只有当业务上允许字段不存在时,才适合这样处理。 如果某个键按设计必须存在,直接使用 user["name"] 反而可以让错误更早暴露。

3. 遍历字典时同时取得键和值

user = {
    "name": "Tom",
    "age": 20,
    "language": "Python"
}

for key, value in user.items():
    print(key, value)

示例输出:

name Tom
age 20
language Python

如果只需要键,可以直接遍历字典;需要键和值时,使用 items() 更清楚。

4. 用字典统计出现次数

字典还很适合做计数。下面统计一组语言名称出现了多少次:

languages = ["Python", "PHP", "Python", "Java", "Python", "PHP"]

counts = {}

for language in languages:
    counts[language] = counts.get(language, 0) + 1

print(counts)

示例输出:

{'Python': 3, 'PHP': 2, 'Java': 1}

这里的关键不是字典本身有“计数功能”,而是每一种语言都可以作为键,对应的值保存出现次数。

SVG 配图 2
图2:选择列表、字典还是集合,可以从“键值关系、唯一性、顺序”三个问题开始判断。

四、集合:去重和成员判断更直接

集合与列表最大的区别之一,是集合不会保留重复元素。 如果业务本身只关心“某个值有没有出现”,而不关心同一个值出现几次,集合往往更符合数据本身的含义。

1. 使用集合完成去重

tags = ["Python", "教程", "Python", "入门", "教程"]

unique_tags = set(tags)

print(unique_tags)

输出中的元素只会各保留一份。需要注意,集合不应该用于依赖固定位置索引的场景,因此不要把 set 当成“自动去重版列表”来理解。

如果最终仍然需要列表,可以进行转换:

tags = ["Python", "教程", "Python", "入门", "教程"]

unique_tags = list(set(tags))

print(unique_tags)
注意: 如果你的任务要求保留原始出现顺序,不应仅依赖 list(set(data))。 这种写法解决的是“得到唯一元素”,不是“按原顺序去重”。

2. 判断元素是否存在

例如有一组允许访问后台的角色:

allowed_roles = {"admin", "editor", "author"}

role = "editor"

if role in allowed_roles:
    print("允许访问")
else:
    print("拒绝访问")

示例输出:

允许访问

这种场景只关心“是否包含某个值”,没有必要维护元素的位置,因此集合比列表更贴近需求。

3. 交集、并集和差集

集合的另一个优势,是可以直接表达两组数据之间的关系。 例如两个用户分别关注了一些技术标签:

user_a = {"Python", "Linux", "Docker"}
user_b = {"Python", "Java", "Docker"}

# 两个人都关注
common = user_a & user_b

# 两个人关注的全部标签
all_tags = user_a | user_b

# A关注而B没有关注
only_a = user_a - user_b

print(common)
print(all_tags)
print(only_a)

这里三个符号分别表达:

  • &:交集,两边都存在。
  • |:并集,合并两边所有唯一元素。
  • -:差集,只保留左边有、右边没有的元素。
SVG 配图 3
图3:列表与集合并不是谁替代谁,而是在“顺序、重复、唯一性”上表达不同的数据含义。

五、相同需求下,选对结构比写复杂代码更重要

初学时容易出现一种情况:已经习惯列表,于是不管什么数据都先放进列表。 数据量小时代码往往也能运行,但随着逻辑增加,会出现大量遍历和判断。

例如,要根据用户 ID 保存多个用户名,可以使用列表:

users = [
    {"id": 101, "name": "Tom"},
    {"id": 102, "name": "Alice"},
    {"id": 103, "name": "Bob"}
]

target_id = 102

for user in users:
    if user["id"] == target_id:
        print(user["name"])
        break

这段代码没有错误。如果主要需求是按照原始顺序依次展示用户,这样的列表很合理。

但如果程序的核心操作变成了“反复根据 ID 找到用户名”,数据关系其实更接近 ID → 用户名:

users = {
    101: "Tom",
    102: "Alice",
    103: "Bob"
}

print(users[102])

示例输出:

Alice

两种做法解决的是略有不同的问题。列表强调“这一批用户按照什么顺序排列”,字典强调“给定一个 ID,对应哪个用户”。 差异重要的地方并不是少写了几行代码,而是数据结构与实际访问方式保持一致。

六、列表、字典和集合可以组合使用

实际程序中的数据通常不会只用一种结构。 例如一篇文章可以使用字典表示,而文章列表又可以由多个字典组成:

articles = [
    {
        "id": 101,
        "title": "Python列表入门",
        "tags": {"Python", "列表", "入门"}
    },
    {
        "id": 102,
        "title": "Python字典用法",
        "tags": {"Python", "字典"}
    }
]

print(articles[0]["title"])
print("Python" in articles[1]["tags"])

示例输出:

Python列表入门
True

这个结构中三种数据结构各自承担了不同职责:

  • 外层列表负责保存多篇文章,并允许按照顺序遍历。
  • 每篇文章用字典保存 ID、标题、标签等字段。
  • 标签使用集合,表示标签不能重复,并方便判断某个标签是否存在。

这比强行把所有数据都塞进同一种结构更容易理解,也更方便后续修改。

七、几个容易混淆的高效用法

1. 判断是否存在:不要先手工遍历

如果只是判断一个值是否存在,直接使用 in:

languages = ["Python", "Java", "PHP"]

if "Python" in languages:
    print("已存在")

如果程序需要频繁判断大量唯一值是否存在,可以进一步考虑把这批数据保存为集合,而不是每次都自己写循环。

2. 不要一边遍历列表,一边随意删除元素

例如想删除所有小于 60 的成绩,与其边遍历边删除,更适合直接构造一个新列表:

scores = [95, 42, 68, 55, 87]

scores = [score for score in scores if score >= 60]

print(scores)

示例输出:

[95, 68, 87]

遍历过程中修改正在遍历的列表,容易导致某些元素被跳过。过滤数据时生成新列表通常更直观。

3. 空集合不能写成 {}

这是初学者很容易遇到的区别:

empty_dict = {}
empty_set = set()

print(type(empty_dict))
print(type(empty_set))

示例输出:

<class 'dict'>
<class 'set'>

{} 表示空字典。要创建空集合,必须使用 set()。

4. 集合元素和字典键需要可哈希

字符串、数字、元组等常见不可变对象通常可以作为集合元素或字典键。 列表本身是可变对象,因此不能直接作为集合元素或字典键。

# 可以
coordinates = {
    (10, 20): "A点",
    (30, 40): "B点"
}

# 不可以把列表直接作为字典键
# data = {[10, 20]: "A点"}

如果一组数据需要作为键使用,又不应该被修改,可以考虑用元组 tuple 表示。

八、一个完整例子:整理文章标签

下面把列表、字典和集合放到同一个小任务中。 假设程序接收到多篇文章,需要统计每个标签出现在哪些文章中。

articles = [
    {
        "id": 101,
        "title": "Python列表入门",
        "tags": ["Python", "列表", "入门", "Python"]
    },
    {
        "id": 102,
        "title": "Python字典入门",
        "tags": ["Python", "字典", "入门"]
    },
    {
        "id": 103,
        "title": "Linux基础命令",
        "tags": ["Linux", "命令", "入门"]
    }
]

tag_articles = {}

for article in articles:
    unique_tags = set(article["tags"])

    for tag in unique_tags:
        if tag not in tag_articles:
            tag_articles[tag] = []

        tag_articles[tag].append(article["id"])

for tag, article_ids in tag_articles.items():
    print(tag, article_ids)

这个例子中:

  1. articles 使用列表,因为需要保存多篇文章。
  2. 单篇文章使用字典,因为 ID、标题和标签都是明确字段。
  3. set(article["tags"]) 用于删除同一篇文章中的重复标签。
  4. tag_articles 使用字典,因为需要建立“标签 → 文章 ID 列表”的对应关系。

可以看到,所谓“高效使用数据结构”并不是寻找一种万能写法,而是让每一种结构负责它擅长表达的关系。

SVG 配图 4
图4:遇到新需求时,可以先从顺序、键值关系和唯一性三个角度快速判断使用哪种数据结构。

九、如何快速判断该用哪一种

实际写代码时,可以按下面的方式判断:

  • 如果你会问“第几个元素是什么”,通常优先考虑列表。
  • 如果你会问“这个键对应什么值”,通常优先考虑字典。
  • 如果你会问“这个值有没有出现过”,并且不关心重复次数,通常可以考虑集合。
  • 如果需要按照原始顺序保存重复数据,不要因为想去重就直接把整个数据结构改成集合。
  • 如果同一批数据同时存在不同关系,可以组合使用列表、字典和集合,而不是强行三选一。
总结: Python 的列表、字典和集合并不是三种相似容器的不同写法,而是三种不同的数据组织方式。 列表解决顺序问题,字典解决映射问题,集合解决唯一性和集合关系问题。 初学阶段不必追求复杂技巧,先让数据结构和真实需求保持一致,再使用 append()、get()、items()、in、 集合运算和推导式等常用功能,代码通常就会更加清晰,也更容易维护。
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。