一、列表与元组:批量管理一组数据

1. 为什么需要列表

如果只保存几个数据,可以用多个变量:

score1 = 90
score2 = 85
score3 = 100

但如果有几十个成绩,这种写法就不现实了。
这时就可以使用列表:

scores = [90, 85, 100, 76, 88]

列表是一种批量保存数据的容器。

2. 创建列表

empty_list1 = []
empty_list2 = list()

numbers = [1, 2, 3, 4]
mixed = [1, "hello", True]

Python 列表可以存放不同类型的数据,但实际开发中通常建议一个列表中尽量存放同类数据。

3. 访问和修改列表元素

列表使用下标访问元素,下标从 0 开始。

numbers = [10, 20, 30, 40]

print(numbers[0])  # 10
print(numbers[2])  # 30

numbers[2] = 300
print(numbers)

有效下标范围:

0 ~ len(列表) - 1

如果下标越界,会报错:

numbers = [10, 20, 30]
print(numbers[100])

4. 负数下标

负数下标表示从后往前数:

numbers = [10, 20, 30, 40]

print(numbers[-1])  # 40
print(numbers[-2])  # 30

5. 切片操作

切片可以一次取出一段子列表:

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

print(numbers[1:4])  # [2, 3, 4]

切片区间是前闭后开:

[开始下标, 结束下标)

也就是说包含开始下标,不包含结束下标。

省略边界:

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

print(numbers[2:])   # 从下标 2 到末尾
print(numbers[:3])   # 从开头到下标 3 之前
print(numbers[:])    # 复制整个列表

指定步长:

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

print(numbers[::2])   # [1, 3, 5, 7]
print(numbers[::-1])  # 反转列表

切片越界不会报错:

numbers = [1, 2, 3]
print(numbers[10:20])  # []

6. 遍历列表

直接遍历元素:

names = ["张三", "李四", "王五"]

for name in names:
    print(name)

按照下标遍历:

names = ["张三", "李四", "王五"]

for i in range(len(names)):
    print(i, names[i])

使用 while 遍历:

names = ["张三", "李四", "王五"]

i = 0
while i < len(names):
    print(names[i])
    i += 1

7. 新增元素

尾插:

names = ["张三", "李四"]
names.append("王五")
print(names)

指定位置插入:

names = ["张三", "王五"]
names.insert(1, "李四")
print(names)

8. 查找元素

使用 in 判断元素是否存在:

names = ["张三", "李四", "王五"]

print("李四" in names)
print("赵六" in names)

使用 index 查找下标:

names = ["张三", "李四", "王五"]
print(names.index("李四"))

如果元素不存在,index 会报错。

9. 删除元素

删除最后一个元素:

names = ["张三", "李四", "王五"]
names.pop()
print(names)

按照下标删除:

names = ["张三", "李四", "王五"]
names.pop(1)
print(names)

按照值删除:

names = ["张三", "李四", "王五"]
names.remove("李四")
print(names)

10. 连接列表

使用 + 生成新列表:

a = [1, 2, 3]
b = [4, 5, 6]
c = a + b

print(c)
print(a)
print(b)

使用 extend 修改原列表:

a = [1, 2, 3]
b = [4, 5, 6]

a.extend(b)
print(a)
print(b)

11. 元组

元组和列表很像,但元组创建后不能修改。

point = (10, 20)
print(point[0])
print(point[1])

空元组:

t1 = ()
t2 = tuple()

元组不支持修改:

point = (10, 20)
point[0] = 100  # 报错

12. 列表和元组的选择

场景 推荐类型
数据需要增删改 列表
数据创建后不应该改变 元组
需要作为字典 key 元组
函数返回多个值 通常是元组

注意事项

  1. 列表下标从 0 开始。
  2. 普通下标越界会报错,切片越界不会报错。
  3. 列表可变,元组不可变。
  4. 不要把变量名写成 list,否则会覆盖 Python 内置函数。

二、字典:用 key 快速找到 value

1. 概念

字典是一种保存 键值对 的数据结构。

key -> value
键  -> 值

例如学生信息:

student = {
    "id": 1001,
    "name": "张三",
    "score": 90
}

其中:

  • "id""name""score" 是 key;
  • 1001"张三"90 是 value。

2. 创建字典

空字典:

d1 = {}
d2 = dict()

带初始值的字典:

student = {
    "id": 1001,
    "name": "张三",
    "score": 90,
}

最后一个键值对后面可以加逗号,也可以不加。多行书写时,推荐加上,后续增删更方便。

3. 判断 key 是否存在

student = {
    "id": 1001,
    "name": "张三",
}

print("id" in student)
print("score" in student)

注意:in 判断的是 key,不是 value。

4. 通过 key 获取 value

student = {
    "id": 1001,
    "name": "张三",
}

print(student["id"])
print(student["name"])

如果 key 不存在,会报错:

print(student["score"])

更安全的写法是使用 get

print(student.get("score"))
print(student.get("score", 0))

5. 新增和修改键值对

如果 key 不存在,就是新增:

student = {
    "id": 1001,
    "name": "张三",
}

student["score"] = 90
print(student)

如果 key 已经存在,就是修改:

student["score"] = 95
print(student)

6. 删除键值对

student = {
    "id": 1001,
    "name": "张三",
    "score": 90,
}

student.pop("score")
print(student)

7. 遍历字典

直接遍历字典,得到的是 key:

student = {
    "id": 1001,
    "name": "张三",
    "score": 90,
}

for key in student:
    print(key, student[key])

获取所有 key:

print(student.keys())

获取所有 value:

print(student.values())

获取所有键值对:

print(student.items())

常用遍历写法:

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

8. 什么类型可以作为 key

字典底层依赖哈希表,因此 key 必须是可哈希对象。

可以计算哈希值的对象通常可以作为 key:

print(hash(1))
print(hash(3.14))
print(hash("hello"))
print(hash(True))
print(hash((1, 2)))

列表和字典本身是可变对象,不能作为 key:

# print(hash([1, 2, 3]))  # 报错
# print(hash({"id": 1}))  # 报错

注意事项

  1. 字典是围绕 key 展开的。
  2. 访问不存在的 key 会报错,可以先用 in 判断,或使用 get
  3. 字典 key 必须是可哈希对象。
  4. 字典适合表示“映射关系”,例如学号到学生、用户名到密码、商品编号到商品信息。

三、文件操作:让数据持久保存

1. 文件是什么

变量保存在内存中,程序结束或电脑重启后,变量中的数据就会消失。
如果希望数据长期保存,就需要把数据写入文件。

常见文件类型:

  • 文本文件:.txt.md.py
  • 图片文件:.jpg.png
  • 视频文件:.mp4
  • Office 文件:.docx.pptx

Python 入门阶段主要学习文本文件读写。

2. 文件路径

路径用于描述文件所在位置。

Windows 绝对路径示例:

D:/test.txt

也可以写成:

D:\test.txt

但在 Python 字符串中,反斜杠 \ 可能会被当作转义符,因此更推荐使用 /,或者使用原始字符串:

path1 = "D:/test.txt"
path2 = r"D:\test.txt"

3. 打开和关闭文件

使用 open 打开文件:

f = open("D:/test.txt", "r", encoding="utf-8")
f.close()

open 常见参数:

模式 含义
"r" 只读
"w" 写入,会清空原内容
"a" 追加写入,不清空原内容

文件使用完后要调用 close() 关闭。

4. 写文件

f = open("D:/test.txt", "w", encoding="utf-8")
f.write("hello Python\n")
f.write("你好,文件\n")
f.close()

注意:"w" 模式会清空原文件内容。

追加写入:

f = open("D:/test.txt", "a", encoding="utf-8")
f.write("这是追加内容\n")
f.close()

5. 读文件

读取指定字符数:

f = open("D:/test.txt", "r", encoding="utf-8")
content = f.read(5)
print(content)
f.close()

读取全部内容:

f = open("D:/test.txt", "r", encoding="utf-8")
content = f.read()
print(content)
f.close()

逐行读取:

f = open("D:/test.txt", "r", encoding="utf-8")
for line in f:
    print(line, end="")
f.close()

使用 readlines 读取所有行:

f = open("D:/test.txt", "r", encoding="utf-8")
lines = f.readlines()
print(lines)
f.close()

6. 关闭文件

更推荐使用 with

with open("D:/test.txt", "r", encoding="utf-8") as f:
    content = f.read()
    print(content)

with 代码块结束后,Python 会自动关闭文件,即使中间出现异常,也更安全。

7. 编码问题

如果文件中有中文,可能出现乱码或报错。
原因是文件本身的编码和 Python 读取时指定的编码不一致。

常见编码:

  • UTF-8
  • GBK

推荐明确指定编码:

with open("D:/test.txt", "r", encoding="utf-8") as f:
    print(f.read())

如果文件是 GBK 编码:

with open("D:/test.txt", "r", encoding="gbk") as f:
    print(f.read())

注意事项

  1. 打开文件后要关闭,推荐使用 with
  2. "w" 会清空原文件内容,使用前要确认。
  3. 读取中文文件时建议显式指定 encoding
  4. 路径推荐使用 / 或原始字符串 r"..."

四、综合案例:学生成绩管理小程序

下面用函数、列表、字典和文件操作做一个小案例:管理学生成绩,并保存到文件。

1. 数据结构设计

每个学生用字典表示:

student = {
    "id": "1001",
    "name": "张三",
    "score": 90
}

多个学生用列表保存:

students = [
    {"id": "1001", "name": "张三", "score": 90},
    {"id": "1002", "name": "李四", "score": 85},
]

2. 完整代码

def add_student(students, student_id, name, score):
    """新增学生信息"""
    student = {
        "id": student_id,
        "name": name,
        "score": score,
    }
    students.append(student)


def find_student(students, student_id):
    """根据学号查找学生"""
    for student in students:
        if student["id"] == student_id:
            return student
    return None


def calc_average(students):
    """计算平均分"""
    if not students:
        return 0

    total = 0
    for student in students:
        total += student["score"]
    return total / len(students)


def save_students(students, filename):
    """把学生信息保存到文本文件"""
    with open(filename, "w", encoding="utf-8") as f:
        for student in students:
            line = f"{student['id']},{student['name']},{student['score']}\n"
            f.write(line)


def load_students(filename):
    """从文本文件读取学生信息"""
    students = []
    with open(filename, "r", encoding="utf-8") as f:
        for line in f:
            student_id, name, score = line.strip().split(",")
            students.append({
                "id": student_id,
                "name": name,
                "score": int(score),
            })
    return students


students = []

add_student(students, "1001", "张三", 90)
add_student(students, "1002", "李四", 85)
add_student(students, "1003", "王五", 96)

student = find_student(students, "1002")
print(student)

average = calc_average(students)
print(f"平均分:{average:.2f}")

save_students(students, "students.txt")

new_students = load_students("students.txt")
print(new_students)

3. 案例分析

这个案例综合使用了:

  • 函数:add_studentfind_studentcalc_averagesave_studentsload_students
  • 列表:保存多个学生;
  • 字典:保存一个学生的多个属性;
  • 文件:保存和读取学生数据;
  • 返回值:查找学生、计算平均分、加载文件都使用了返回值;
  • with open:安全打开和关闭文件。

4. 改进方向

如果继续优化,可以加入:

  • 删除学生;
  • 修改成绩;
  • 按成绩排序;
  • 处理文件不存在异常;
  • 使用 JSON 文件保存更结构化的数据;
  • 制作命令行菜单。

五、常见坑点与学习建议

1. 函数相关坑点

  • 函数定义不会自动执行,必须调用。
  • 函数要先定义再调用。
  • 参数个数要匹配。
  • 不要在函数里混合太多职责,例如既计算又打印又写文件。
  • 少用全局变量,优先使用参数和返回值。

2. 列表和元组相关坑点

  • 列表下标从 0 开始。
  • alist[100] 会报错,但 alist[100:200] 不会报错。
  • append 是尾插,insert 是指定位置插入。
  • pop 按下标删除,remove 按值删除。
  • 元组不可修改,列表可以修改。

3. 字典相关坑点

  • in 判断的是 key 是否存在。
  • student["score"] 在 key 不存在时会报错。
  • 可以使用 student.get("score", 0) 提供默认值。
  • 列表、字典不能作为字典 key。

4. 文件相关坑点

  • "w" 模式会清空文件。
  • 文件打开后要关闭,推荐 with
  • 中文文件要注意编码,必要时指定 encoding="utf-8"encoding="gbk"
  • Windows 路径建议写成 D:/test.txtr"D:\test.txt"

5. 学习建议

  1. 多写函数:把重复逻辑封装起来,练习参数和返回值。
  2. 多画图理解容器:列表是有顺序的一组数据,字典是 key 到 value 的映射。
  3. 用小案例串联知识点:例如通讯录、成绩管理、图书管理。
  4. 遇到报错先读错误信息:下标越界、key 不存在、文件路径错误、编码错误都是初学阶段常见问题。
  5. 养成写注释的习惯:特别是函数功能、参数含义、返回值含义。

 

总结

Python 基础语法并不只是记住几个关键字,更重要的是理解每种语法解决什么问题:

  • 函数解决 代码复用和逻辑封装
  • 参数和返回值解决 函数与外部的数据交换
  • 作用域解决 变量在哪里生效
  • 递归解决 问题可以拆成同类子问题 的场景;
  • 列表和元组解决 一组有序数据的管理
  • 字典解决 键值映射和快速查找
  • 文件解决 数据持久保存

 

更多推荐