Python基础语法练习题及答案:变量、循环与列表操作详解

花开有时
花开有时
发布时间:2026-11-11| 2人浏览过
原创

精选Python基础语法核心练习题,涵盖变量赋值与深浅拷贝、for与while循环控制、列表增删改查与列表推导式,提供完整代码答案、执行逻辑与内联SVG原理图解。

模块:Python 核心基础 目标:夯实语法应用、避免常见逻辑陷阱 适用:初学者与基础巩固
Python基础语法练习题及答案:变量、循环与列表操作详解
图 1:Python 基础语法核心技能全景架构
很多初学者在刚接触 Python 时,能看懂基础语法概念,但在面对具体问题时往往不知如何落笔,或者因为“变量引用”、“循环中修改容器”等机制理解不深而产生隐藏 Bug。本文直接聚焦变量赋值与引用机制、for/while 循环控制、列表操作与推导式三大高频考点,精选典型练习题,并给出完整的代码实现、分步原理解释与易错提醒。

第一部分:变量赋值、解包与对象引用机制

在 Python 中,“变量”并不是存储数据的盒子,而是贴在内存对象上的标签(引用)。理解变量名与底层对象的关系,是编写正确程序的前提。

练习 1 变量解包与就地数值交换

题目要求:给定两个变量 x = 100 和 y = 200,要求在不引入显式临时变量的前提下,完成两者的值交换。随后,使用一行代码将列表 data = ["Alice", 95, 88, 92, "A"] 中的姓名、三次成绩列表和等级分别提取到独立变量中。

参考解答

solution_1.pyPython 3
# 任务 1:多元赋值交换变量
x = 100
y = 200
x, y = y, x

print(f"交换后: x = {x}, y = {y}")

# 任务 2:扩展序列解包(Extended Sequence Unpacking)
data = ["Alice", 95, 88, 92, "A"]
name, *scores, grade = data

print(f"姓名: {name}")
print(f"成绩列表: {scores}")
print(f"综合评级: {grade}")
示例输出
交换后: x = 200, y = 100 姓名: Alice 成绩列表: [95, 88, 92] 综合评级: A

代码原理解析:

  1. x, y = y, x 的执行逻辑是:Python 解释器先在底层构造一个元组 (y, x),计算出对应的值;随后将元组按位置解包,依次将引用绑定给左侧的 x 和 y。这一过程天然规避了值覆盖问题。
  2. 在 name, *scores, grade = data 中,带星号的变量 *scores 会贪婪匹配中间所有未被首尾变量捕获的元素,并将它们打包为一个新的列表(即使匹配到0个元素也是空列表)。
练习 2 可变对象赋值与拷贝机制陷阱

题目要求:分析以下代码片段,写出最终输出结果,并修改代码使 b 的修改不会污染原始列表 a:

problem_snippet.pyPython 3
a = [1, [2, 3], 4]
b = a
b[0] = 99
b[1].append(100)
# 此时 a 的值是什么?为什么?

参考解答与修正方案

solution_2.pyPython 3
import copy

# 1. 直接赋值产生的问题演示
a = [1, [2, 3], 4]
b = a
b[0] = 99
b[1].append(100)
print("直接赋值后 a 的值:", a)  # 此时 a 变成了 [99, [2, 3, 100], 4]

# 2. 正确解决方案:使用深拷贝隔离嵌套对象
original = [1, [2, 3], 4]
safe_clone = copy.deepcopy(original)

safe_clone[0] = 888
safe_clone[1].append(999)

print("修改 safe_clone 后 original:", original)
print("修改后的 safe_clone:", safe_clone)
示例输出
直接赋值后 a 的值: [99, [2, 3, 100], 4] 修改 safe_clone 后 original: [1, [2, 3], 4] 修改后的 safe_clone: [888, [2, 3, 999], 4]
易错提醒:copy.copy()(浅拷贝)只会复制最外层容器,内部嵌套的子列表依然共享内存地址。只有 copy.deepcopy() 会递归复制所有子对象。
Python基础语法练习题及答案:变量、循环与列表操作详解
图 2:直接赋值与深拷贝在底层内存分配中的引用关系对比

第二部分:循环控制流(for、while 与分支跳转)

Python 循环包含两种基本形式:适用于确定序列遍历的 for 循环,以及适用于动态条件等待的 while 循环。结合 break、continue 与循环专属的 else 语法,能够优雅地实现复杂检索与流程控制。

练习 3 双序列同步遍历与索引步进(for + zip + enumerate)

题目要求:现有两个并列数据列表:学生学号 student_ids = ["S101", "S102", "S103", "S104"],学生得分 scores = [78, 92, 59, 84]。要求打印出带序号的及格(得分 ≥ 60)名单,格式为:序号: 1 | 学号: S101 | 成绩: 78;对不及格项予以标记。

参考解答

solution_3.pyPython 3
student_ids = ["S101", "S102", "S103", "S104"]
scores = [78, 92, 59, 84]

passed_rank = 1

# 使用 zip 将两个列表打包为二元组序列,并从 0 遍历
for idx, (sid, score) in enumerate(zip(student_ids, scores), start=1):
    if score < 60:
        print(f"[警告] 原始行 {idx}: 学号 {sid} 成绩为 {score} 分,未达到及格线!")
        continue
    
    print(f"序号: {passed_rank} | 学号: {sid} | 成绩: {score}")
    passed_rank += 1
示例输出
序号: 1 | 学号: S101 | 成绩: 78 序号: 2 | 学号: S102 | 成绩: 92 [警告] 原始行 3: 学号 S103 成绩为 59 分,未达到及格线! 序号: 3 | 学号: S104 | 成绩: 84

核心解析:很多初学者习惯用 range(len(student_ids)) 做下标索引,这种写法不仅冗长,而且容易在索引越界时报错。通过 zip() 进行组合,再由 enumerate() 提供计数器,既符合 Pythonic 风格,又保障了代码简洁度。

练习 4 状态退出与循环 else 子句(素数检测)

题目要求:编写一段程序,利用 for ... else 机制判断正整数 n = 29 是否为质数(素数)。如果找到能整除它的数则打印出因数并立刻终止;若循环正常结束未被中途打断,则确认其为质数。

参考解答

solution_4.pyPython 3
import math

def check_prime(n: int):
    if n <= 1:
        print(f"{n} 不是质数(质数定义为大于 1 的自然数)")
        return

    # 只需要检查到根号 n
    limit = int(math.isqrt(n))
    
    for divisor in range(2, limit + 1):
        if n % divisor == 0:
            print(f"{n} 是合数,因数包括: {divisor} (与 {n // divisor})")
            break
    else:
        # 当 for 循环正常跑完且没有触发 break 时,才会执行 else
        print(f"{n} 是一个质数!")

# 验证测试
check_prime(29)
check_prime(49)
示例输出
29 是一个质数! 49 是合数,因数包括: 7 (与 7)
机制点拨:在 Python 中,for ... else 或 while ... else 的 else 代码块并不是“条件不满足”的分支,而是“循环没有遇到 break 完整结束后的善后处理”。用它来替代传统设置 flag = True 的写法,能显著减少状态标记变量的使用。
Python基础语法练习题及答案:变量、循环与列表操作详解
图 3:循环执行、条件中断与 else 分支流转判定图

第三部分:列表切片、修改与推导式技巧

列表是 Python 最常用的动态数组容器。灵活掌握切片语法 [start:stop:step] 以及推导式,不仅能让代码更精炼,还能规避“迭代中删除元素”的经典陷阱。

练习 5 在列表中安全过滤元素(规避漏删 Bug)

题目要求:给定一个包含偶数的列表 numbers = [1, 2, 4, 3, 6, 8, 7, 10],要求将其中所有偶数全部删除。初学者常直接在 for x in numbers: 中执行 numbers.remove(x),指出其为何产生 Bug,并给出两种规范解法。

错误代码与成因排查

buggy_example.pyPython 3
# 错误示例:边遍历边删除
nums = [1, 2, 4, 3, 6, 8, 7, 10]
for x in nums:
    if x % 2 == 0:
        nums.remove(x)
print("错误删除结果:", nums)  # 结果居然还保留了偶数 4 和 8!
错误输出
错误删除结果: [1, 4, 3, 8, 7]

Bug 原理解释:列表是连续内存结构。当遍历到索引 1(值为 2)并执行删除后,后面的元素 4 会立即前移至索引 1;而在下一轮循环中,迭代器内部索引自增到 2,导致元素 4 被无声跳过。

正确解法与实现

safe_solution.pyPython 3
# 解法 1:使用列表推导式生成过滤后的全新列表(推荐,最直观高效)
raw_nums = [1, 2, 4, 3, 6, 8, 7, 10]
odds_only = [x for x in raw_nums if x % 2 != 0]
print("解法 1 (列表推导式):", odds_only)

# 解法 2:如果必须在原列表上原地修改,采用倒序切片遍历
in_place_nums = [1, 2, 4, 3, 6, 8, 7, 10]
for i in range(len(in_place_nums) - 1, -1, -1):
    if in_place_nums[i] % 2 == 0:
        del in_place_nums[i]
print("解法 2 (倒序原地删除):", in_place_nums)

# 解法 3:切片替换保留对象 id
in_place_nums2 = [1, 2, 4, 3, 6, 8, 7, 10]
in_place_nums2[:] = [x for x in in_place_nums2 if x % 2 != 0]
print("解法 3 (切片整体替换):", in_place_nums2)
正确输出
解法 1 (列表推导式): [1, 3, 7] 解法 2 (倒序原地删除): [1, 3, 7] 解法 3 (切片整体替换): [1, 3, 7]
Python基础语法练习题及答案:变量、循环与列表操作详解
图 4:Python 序列正向、反向负索引与 step 步长提取关系图解
练习 6 二维矩阵展平与条件推导式转换

题目要求:给定一个 3×3 的二维矩阵 matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]],分别完成:
1. 将矩阵展开为一维列表;
2. 仅保留大于 4 的偶数,并计算其平方;
3. 对矩阵进行行列转置(行变列、列变行)。

参考解答

solution_6.pyPython 3
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

# 任务 1:嵌套推导式展平(双重 for 从外层到内层)
flat = [num for row in matrix for num in row]
print("展平后的一维列表:", flat)

# 任务 2:条件过滤与数值计算
filtered_squares = [num ** 2 for row in matrix for num in row if num > 4 and num % 2 == 0]
print("大于4的偶数平方:", filtered_squares)  # 6^2=36, 8^2=64

# 任务 3:矩阵转置 (两种写法)
# 写法 A: 嵌套列表推导式
transposed = [[row[col] for row in matrix] for col in range(len(matrix[0]))]
print("推导式转置结果:", transposed)

# 写法 B: 更加 Pythonic 的 zip(*) 方式
transposed_zip = [list(col) for col in zip(*matrix)]
print("zip 解包转置结果:", transposed_zip)
示例输出
展平后的一维列表: [1, 2, 3, 4, 5, 6, 7, 8, 9] 大于4的偶数平方: [36, 64] 推导式转置结果: [[1, 4, 7], [2, 5, 8], [3, 6, 9]] zip 解包转置结果: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

理解秘诀:阅读多层列表推导式时,其书写顺序与嵌套 for 循环的嵌套层级完全一致。先写的 for row in matrix 对应最外层循环,后写的 for num in row 对应内层循环,末尾跟条件判断 if ...。

第四部分:综合实战题目(串联变量、循环与容器操作)

在实际项目和面试中,很少单独考查某一个语法点,往往需要综合运用变量解包、多层遍历、容器更新与边界处理。

综合实战 员工考勤与工时异常分析器

题目背景:系统导出一组员工打卡打卡记录日志列表,每条记录为一个元组 (员工ID, 部门, 每日工时列表):

raw_records.pyPython 3
records = [
    ("E01", "技术部", [8.5, 9.0, 8.0, 10.0, 8.5]),
    ("E02", "运营部", [8.0, 7.5, 8.0, 8.0, 7.0]),
    ("E03", "技术部", [9.5, 11.0, 10.5, 9.0, 12.0]),
    ("E04", "市场部", [8.0, 8.5, 8.0]),
    ("E05", "技术部", [8.0, 8.0, 8.0, 8.0, 8.0])
]

功能要求:
1. 过滤掉数据不完整(有效考勤天数少于 5 天)的记录;
2. 计算每位员工的总工时与日均工时;
3. 筛选出“技术部”且日均工时超过 9.0 小时的加班预警员工,输出其工时排序结果(工时由高到低)。

完整代码实现

attendance_analyzer.pyPython 3
def analyze_attendance(raw_data):
    clean_reports = []

    for eid, dept, hours in raw_data:
        # 步骤 1:完整性校验(过滤少于5天的记录)
        if len(hours) < 5:
            continue
        
        # 步骤 2:聚合与均值统计
        total_hours = sum(hours)
        avg_hours = round(total_hours / len(hours), 2)
        
        # 步骤 3:部门与加班预警条件筛选
        if dept == "技术部" and avg_hours > 9.0:
            clean_reports.append({
                "eid": eid,
                "dept": dept,
                "total": total_hours,
                "avg": avg_hours,
                "peak_hour": max(hours)
            })

    # 步骤 4:基于日均工时降序排序 (使用 key 函数)
    clean_reports.sort(key=lambda item: item["avg"], reverse=True)
    return clean_reports

# 执行测试
records = [
    ("E01", "技术部", [8.5, 9.0, 8.0, 10.0, 8.5]),
    ("E02", "运营部", [8.0, 7.5, 8.0, 8.0, 7.0]),
    ("E03", "技术部", [9.5, 11.0, 10.5, 9.0, 12.0]),
    ("E04", "市场部", [8.0, 8.5, 8.0]),
    ("E05", "技术部", [8.0, 8.0, 8.0, 8.0, 8.0])
]

alerts = analyze_attendance(records)
print(f"技术部高负荷预警人数: {len(alerts)}")
for r in alerts:
    print(f"员工编号: {r['eid']} | 总工时: {r['total']}h | 日均工时: {r['avg']}h | 单日峰值: {r['peak_hour']}h")
示例输出
技术部高负荷预警人数: 1 员工编号: E03 | 总工时: 52.0h | 日均工时: 10.4h | 单日峰值: 12.0h
Python基础语法练习题及答案:变量、循环与列表操作详解
图 5:Python 核心语法综合解题与代码防御性设计路径图

总结与日常练习建议

掌握 Python 的核心在于理解“引用而非容器”的底层模型,以及学会用简洁、直观的内置工具表达业务逻辑。建议在日常编码中保持以下三个良好习惯:

  • 善用解包与推导式:多利用 a, b = b, a、enumerate() 以及列表推导式简化代码,减少繁琐的手动索引维护。
  • 留心可变对象的副作用:当需要传递列表、字典并在局部做破坏性修改时,提前评估是否需要 copy.deepcopy()。
  • 避免边遍历边改容器:过滤列表优先选择生成新列表或倒序索引删除,切勿在常规 for ... in 循环内调用 remove() 或 pop()。

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

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 算法库。