当前位置:首页>python>每天学习一点Python——3个经典项目带你玩转数据分析

每天学习一点Python——3个经典项目带你玩转数据分析

  • 2026-09-22 14:00:58
每天学习一点Python——3个经典项目带你玩转数据分析

每天学习一点Python——3个经典项目带你玩转数据分析

大家好,今天我们通过3个非常有趣的Python项目来巩固下昨天学习的元组、列表与字典。

📊 项目一:大学统计数据分析

项目目标

分析大学数据,计算各种统计指标,让数据说话!

数据结构解析

# universities是一个列表,包含7个子列表
# 每个子列表代表一所大学,包含3个元素:[大学名称, 注册人数, 学费]

universities = [
    ['California Institute of Technology', 2175, 37704],
    ['Harvard', 19627, 39849],
    # ... 其他大学数据

]

变量解释:

  • • universities:主列表,存储所有大学数据
  • • 每个子列表索引:0=学校名,1=学生数,2=学费

核心函数详解

函数1:enrollment_stats(universities)

def enrollment_stats(universities):
    # enrollments变量:存储所有大学的注册人数

    # 使用列表推导式:从每所大学(uni)中取第2个元素(索引1)

    enrollments = [uni[1] for uni in universities]

    # tuitions变量:存储所有大学的学费

    # 从每所大学(uni)中取第3个元素(索引2)

    tuitions = [uni[2] for uni in universities]

    # 返回两个列表:注册人数列表和学费列表

    return
 enrollments, tuitions

参数说明:

  • • universities:传入的大学数据列表

返回值:

  • • 第一个值enrollments:所有大学的学生人数列表
  • • 第二个值tuitions:所有大学的学费列表
部分
数据类型
内容示例
enrollments
列表(list)
[2175, 19627, ...]
tuitions
列表(list)
[37704, 39849, ...]
return enrollments, tuitions
元组(tuple)
([2175, 19627, ...], [37704, 39849, ...])

注意: 只要用逗号分隔两个或多个值,Python就会自动将它们打包成一个元组。

函数2:mean(numbers) - 计算平均值

def mean(numbers):
    # 首先检查列表是否为空

    if
 not numbers:
        return
 0  # 如果空列表,返回0

    # 计算平均值 = 总和 ÷ 元素个数

    return
 sum(numbers) / len(numbers)

参数说明:

  • • numbers:需要计算平均值的数字列表

函数3:median(numbers) - 计算中位数

def median(numbers):
    # 检查空列表

    if
 not numbers:
        return
 0

    # sorted_nums:排序后的新列表(原列表不变)

    sorted_nums = sorted(numbers)

    # n:列表中元素的数量

    n = len(sorted_nums)

    # middle:中间位置的索引(整除//只取整数部分)

    middle = n // 2

    if
 n % 2 == 0:  # 如果元素个数是偶数
        # 中位数 = 中间两个数的平均值

        return
 (sorted_nums[middle - 1] + sorted_nums[middle]) / 2
    else
:  # 如果元素个数是奇数
        # 中位数 = 正中间的那个数

        return
 sorted_nums[middle]

数据处理流程

# 第1步:提取数据(元组解包)
# enrollments得到所有学生数:[2175, 19627, 10566, ...]

# tuitions得到所有学费:[37704, 39849, 40732, ...]

enrollments, tuitions = enrollment_stats(universities)

# 第2步:计算总和

total_students = sum(enrollments)  # 所有学生数相加
total_tuition = sum(tuitions)      # 所有学费相加

# 第3步:计算平均值和中位数

student_mean = mean(enrollments)    # 学生平均数
student_median = median(enrollments)# 学生数中位数
tuition_mean = mean(tuitions)       # 学费平均数
tuition_median = median(tuitions)   # 学费中位数

额外分析:找出最贵的大学

most_expensive = max(universities, key=lambda x: x[2])
print
(f"🏫 学费最贵的大学: {most_expensive[0]} (${most_expensive[2]:,})")

🔑 key=lambda x: x[2] 解释

作用: 告诉Python如何提取比较值

拆解:

  • • key=:比较的"依据"
  • • lambda:创建匿名函数
  • • x:代表universities中的每个子列表(如 ['Harvard', 19627, 39849])
  • • x[2]:取每个子列表的第3个元素(学费)

效果: "请按每个大学的学费进行比较"

执行逻辑

# Python内部处理步骤:
1.
 遍历 universities 中的每个大学(每个子列表)
2.
 对每个大学应用 lambda 函数提取学费(x[2])
3.
 比较所有大学的学费
4.
 找到学费最高的大学
5.
 返回该大学的完整信息(整个子列表)

🎮 项目二:州首府测验游戏

项目目标

创建一个交互式的地理知识测验游戏!

数据结构

# capitals_dict:字典类型,存储州名和对应首府
# 格式:{'州名': '首府', ...}

capitals_dict = {
    'Alabama'
: 'Montgomery',
    'Alaska'
: 'Juneau',
    'Arizona'
: 'Phoenix',
    # ... 更多州数据

}

核心函数解析

函数1:quiz_game()

def quiz_game():
    score = 0  # 得分:答对一题加1分
    questions_asked = 0  # 已提问问题数
    max_questions = 5  # 最多提问5题

    # list(capitals_dict.keys()):把字典的所有键转换成一个标准列表,只包含州名。

    states = list(capitals_dict.keys())

字典方法对比:

方法
得到什么
类型
示例
.keys()
所有键(州名)
列表
['Alabama', 'Alaska', ...]
.values()
所有值(首府)
列表
['Montgomery', 'Juneau', ...]
.items()
所有键值对
元组列表
[('Alabama','Montgomery'), ...]

游戏逻辑流程

while questions_asked < max_questions:  # 条件:还没问完5题
    state = random.choice(states)  # 随机选一个州
    correct_capital = capitals_dict[state]  # 根据州名查找对应首府(正确答案)
    attempts = 3  # 每道题最多尝试3次

    while
 attempts > 0:  # 还有尝试机会
        guess = input("你的答案: ").strip()  # 获取用户输入

        if
 guess.lower() == 'exit':  # 退出命令
            return

        elif
 guess.lower() == 'hint':  # 提示命令
            hint = correct_capital[0] + "*" * (len(correct_capital) - 1)
            attempts -= 1
            continue

        elif
 guess.lower() == correct_capital.lower():  # 回答正确
            score += 1
            break

        else
:  # 回答错误
            attempts -= 1

🎲 state = random.choice(states) 解释

功能: 随机选择一个州

效果:

states = ['Alabama', 'Alaska', 'Arizona', 'California']
state = random.choice(states)
# 可能得到:'Alaska'

# 或:'California'

# 或:'Alabama'  ← 每次运行结果不同
部分
作用
random.choice()
随机选择函数
states
州名列表
state
存储被选中的州名

注意: 必须导入 random 模块:import random

🔄 random.sample() 方法(不放回随机取多个元素)

功能: 随机选取多个不重复的元素

语法:random.sample(列表, 要选的数量)

与相关方法对比:

方法
特点
示例
random.choice()取1个
,可能重复多次取到相同元素
抽奖(每次独立)
random.sample()取多个
,保证不重复
抽多人(每人只能中一次)
random.choices()取多个
,可能重复(需指定k)
有放回抽样

函数2:practice_mode()

def practice_mode():
    while
 True:  # 无限循环,直到用户退出
        state_input = input("输入州名: ").strip()

        if
 state_input.lower() == 'quit':
            break
  # 退出循环

        # 检查州名是否在字典中

        if
 state_input in capitals_dict:
            print
(f"✅ {state_input} 的首府是: {capitals_dict[state_input]}")
        else
:
            print
(f"❌ 未找到州 '{state_input}',请检查拼写。")
            print
("可用州名:", ", ".join(sorted(capitals_dict.keys())))

📝 代码解释

 ", ".join(sorted(capitals_dict.keys()))

功能: 把州名列表变成好看的字符串

效果:

# 原始列表:['Alaska', 'Alabama', 'Arizona']
# 处理后:"Alabama, Alaska, Arizona"  ← 排序并用逗号分隔

代码拆解步骤:

  1. 1. capitals_dict.keys() - 获取所有键(州名)
  2. 2. sorted(...) - 按字母排序州名
  3. 3. ", ".join(...) - 用逗号+空格连接

🔄 .join() 方法详解:

列表 = ["苹果", "香蕉", "橙子"]
print
(",".join(列表))        # "苹果,香蕉,橙子"
print
(" | ".join(列表))      # "苹果 | 香蕉 | 橙子"
print
("\n".join(列表))       # 换行显示

🐱 项目三:戴帽子的猫(逻辑谜题)

问题理解

  • • 有100只猫排成一排
  • • 初始时都没有帽子
  • • 第1轮:每只猫都戴帽子(1的倍数)
  • • 第2轮:每隔1只猫操作(2的倍数)
  • • 第3轮:每隔2只猫操作(3的倍数)
  • • ...
  • • 第100轮:每隔99只猫操作(100的倍数)
  • • "操作":有帽子→摘掉,没帽子→戴上

核心函数解析

函数1:cat_hat_problem(num_cats)

def cat_hat_problem(num_cats=100):
    # 创建布尔值列表,表示100只猫的帽子状态

    # False = 没帽子,True = 有帽子

    cats = [False] * num_cats

    # 模拟100轮操作

    for
 round_num in range(1, num_cats + 1):
        # 遍历需要操作的猫

        for
 cat_index in range(round_num - 1, num_cats, round_num):
            # not cats[cat_index]:取反操作

            # True变False,False变True

            cats[cat_index] = not cats[cat_index]

    # 找出戴帽子的猫

    hatted_cats = [index + 1 for index, has_hat in enumerate(cats) if has_hat]

    return
 hatted_cats

📝 代码解释

 range(round_num - 1, num_cats, round_num)

功能: 从第round_num只猫(因为列表索引从0开始)开始,每隔round_num只猫,选取一只进行操作,直到处理完所有num_cats只猫。

📚 基本语法

range(起始值, 结束值, 步长)

📝 cats = [False] * num_cats 解释

功能: 创建全是 False 的列表

效果:

num_cats = 5
cats = [False] * num_cats
print
(cats)  # [False, False, False, False, False]

具体运行示例(简化版:6只猫)

# 初始状态:[猫1:无, 猫2:无, 猫3:无, 猫4:无, 猫5:无, 猫6:无]

# 第1轮:操作索引0,1,2,3,4,5 → 所有猫戴帽子

# 状态:[有, 有, 有, 有, 有, 有]


# 第2轮:操作索引1,3,5 → 猫2,4,6摘帽子

# 状态:[有, 无, 有, 无, 有, 无]


# 第3轮:操作索引2,5 → 猫3摘帽子,猫6戴帽子

# 状态:[有, 无, 无, 无, 有, 有]


# ...继续到第6轮

# 最终状态:[有, 无, 无, 有, 无, 无]

🔍 hatted_cats = [index + 1 for index, has_hat in enumerate(cats) if has_hat] 详解

这是 列表推导式 + enumerate() 的经典用法:

数据示例:

cats = [True, False, False, True, False, False]
# 对应:猫1有帽子, 猫2无, 猫3无, 猫4有, 猫5无, 猫6无

分解步骤:

  1. 1. enumerate(cats) - 得到:[(0,True), (1,False), (2,False), (3,True), (4,False), (5,False)]
  2. 2. for index, has_hat in enumerate(cats) - 遍历每个元组
  3. 3. if has_hat - 只保留有帽子的情况
  4. 4. index + 1 - 索引转猫编号(索引0→猫1)

💡 重要说明:
for index, has_hat in enumerate(cats) 中的 for 后面跟了两个参数,分别是 index 和 has_hat,它们对应的分别是 enumerate(cats) 返回的每个元组中的索引和值。

等价写法:

# 写法1:列表推导式(简洁)
hatted_cats = [index + 1 for index, has_hat in enumerate(cats) if has_hat]

# 写法2:普通for循环

hatted_cats = []
for
 index in range(len(cats)):
    if
 cats[index]:
        hatted_cats.append(index + 1)

# 写法3:使用enumerate的for循环

hatted_cats = []
for
 index, has_hat in enumerate(cats):
    if
 has_hat:
        hatted_cats.append(index + 1)

可视化函数

def visualize_cats(num_cats=20):
    cats = [False] * num_cats  # 初始化20只猫

    for
 round_num in range(1, num_cats + 1):
        # 操作

        for
 cat_index in range(round_num - 1, num_cats, round_num):
            cats[cat_index] = not cats[cat_index]

        # 转换为表情符号:🎩表示有帽子,🐱表示没帽子

        status = ["🎩" if has_hat else "🐱" for has_hat in cats]

        # 显示状态

        print
(f"第{round_num:2d}轮: {' '.join(status)}")

💡 学习要点总结

  1. 1. 列表处理:学会了如何从复杂列表中提取数据
  2. 2. 函数设计:每个函数只做一件事,提高代码可读性
  3. 3. 字典应用:用键值对存储相关数据(州-首府)
  4. 4. 算法思维:通过模拟找到数学规律
  5. 5. 交互编程:让程序与用户对话

这三个项目从不同角度展示了Python的强大功能:数据分析、游戏开发和逻辑推理。建议你亲自运行并手动编写这些代码,尝试修改参数,看看会产生什么不同的结果。

请记住:编程最好的学习方法就是动手实践!遇到问题不要怕,多尝试、多修改,你会在实践中快速成长。


📦 资源获取提示

关注「码农自习室」,后台回复关键词 Python学习,即可获取本文完整代码,一起动手掌握高效编程的核心技巧!


❤️ 支持我们

如果觉得本文对你有帮助,欢迎点赞 + 关注,您的支持是我们持续创作优质内容的最大动力!


📚 学习资源说明

本文内容是基于《Python Basics: A Practical Introduction to Python 3》(Real Python)一书的学习笔记整理。
这本书是一本非常优秀的Python入门教材,推荐给所有想要系统学习Python的朋友们。

这本书的特点:

  • • ✅ 完全面向编程新手
  • • ✅ 每个概念都有代码示例
  • • ✅ 包含大量练习题
  • • ✅ 由经验丰富的Python开发者编写

跟着这本书学习,配合我的笔记整理,相信你能更快掌握Python编程!

让我们一起坚持学习,每天进步一点点!💪

最新文章

随机文章