0

0

如何将键为电影、值为演员列表的字典反转为键为演员、值为电影列表的字典

碧海醫心

碧海醫心

发布时间:2026-01-07 16:58:22

|

615人浏览过

|

来源于php中文网

原创

如何将键为电影、值为演员列表的字典反转为键为演员、值为电影列表的字典

本文详解如何将原始字典(电影→[演员列表])高效反转为演员索引字典(演员→[电影列表]),并处理真实数据中常见的换行断裂问题,最终实现按演员名快速查询参演影片的功能。

在影视数据处理中,常需从“电影→演员”映射切换为“演员→电影”索引,以支持按人查片等交互需求。原始代码构建的是 movie_dictionary = {"La La Land": ["Ryan Gosling", "Emma Stone"], ...},但用户需要输入演员名(如 "Harrison Ford")后,直接获取其所有参演影片。这本质上是字典的键值反转,但由于值为列表且存在一对多关系,不能简单使用 {v: k for k, v in d.items()} —— 必须将每个演员作为新键,将其出现的所有电影逐个追加到对应列表中。

✅ 正确的反转逻辑:遍历 + setdefault()

核心思路是:对每一行数据,先分离出电影名和演员列表;再对每位演员(需 .strip() 清理空格),使用 dict.setdefault(key, []) 确保该演员键存在且值为列表,然后 .append(movie):

# 示例:模拟读取文件后的数据行
rows = [
    "La La Land, Ryan Gosling, Emma Stone",
    "Blade Runner 2049, Harrison Ford, Ryan Gosling, Ana de Armas",
    # ... 其他行(已确保格式完整)
]

appears_in = {}  # 反转后的字典:演员 → [电影列表]
for row in rows:
    parts = row.split(',')
    movie = parts[0].strip()
    actors = [a.strip() for a in parts[1:]]  # 清理每位演员首尾空格
    for actor in actors:
        appears_in.setdefault(actor, []).append(movie)

✅ setdefault() 是关键:若 actor 键不存在,则初始化为空列表 [] 并返回该列表;若已存在,则直接返回原列表。后续 .append(movie) 安全追加,避免 KeyError 或重复初始化。

Aha
Aha

全天候网红营销AI智能体平台

下载

⚠️ 真实数据陷阱:换行导致的字段断裂

观察原始 movies and actors.txt,部分行末尾有换行符中断(如 "My Best Friend's Wedding, Julia Roberts, dermont Multroney, \nCameron Diaz"),导致 split(',') 后出现孤立的 " Cameron Diaz" 作为独立行,破坏结构。

修复策略:合并被截断的行
遍历每行,若某行 split(',') 后仅得 1 段(即无逗号),说明它是上一行的延续,应拼接到前一行末尾:

def fix_broken_lines(raw_lines):
    fixed = []
    buffer = ""
    for line in raw_lines:
        line = line.strip()
        if not line:
            continue
        parts = line.split(',')
        if len(parts) == 1 and buffer:  # 孤立片段,追加到缓冲区
            buffer += ", " + line
        else:
            if buffer:
                fixed.append(buffer)
            buffer = line
    if buffer:
        fixed.append(buffer)
    return fixed

# 使用示例
with open("movie and actors.txt", "r") as f:
    raw_rows = f.readlines()
fixed_rows = fix_broken_lines(raw_rows)

? 完整可运行程序(含错误处理)

def build_actor_movie_index(filename):
    """从文件构建演员→电影列表字典,自动修复换行断裂"""
    with open(filename, "r", encoding="utf-8") as f:
        lines = f.readlines()

    # 步骤1:修复断裂行
    rows = []
    buffer = ""
    for line in lines:
        stripped = line.strip()
        if not stripped:
            continue
        if "," not in stripped and buffer:  # 无逗号且有前置内容 → 属于上一行
            buffer += " " + stripped
        else:
            if buffer:
                rows.append(buffer)
            buffer = stripped
    if buffer:
        rows.append(buffer)

    # 步骤2:构建反转字典
    appears_in = {}
    for row in rows:
        parts = row.split(',')
        if len(parts) < 2:
            continue  # 跳过无效行
        movie = parts[0].strip()
        actors = [a.strip() for a in parts[1:] if a.strip()]
        for actor in actors:
            appears_in.setdefault(actor, []).append(movie)

    return appears_in

# 主程序
if __name__ == "__main__":
    try:
        index = build_actor_movie_index("movie and actors.txt")
        name = input("Enter an actor/actress name: ").strip()

        if name in index:
            movies = index[name]
            print(f"The movies that '{name}' starred in are: {', '.join(movies)}")
        else:
            print(f"No movies found for '{name}'. Check spelling or try another name.")

    except FileNotFoundError:
        print("Error: File 'movie and actors.txt' not found.")
    except Exception as e:
        print(f"An error occurred: {e}")

? 关键总结

  • 不要用 dict(zip(values, keys)):因原值是列表,会丢失多对一关系;
  • 优先用 setdefault():比手动 if key not in d: d[key] = [] 更简洁安全;
  • 务必清洗数据:.strip() 处理空格,预处理修复换行断裂;
  • 增强健壮性:加入 try/except 和空行/无效行过滤;
  • 用户体验优化:提示拼写检查,避免 KeyError 导致程序崩溃。

通过以上方法,你不仅能正确反转字典结构,还能应对真实数据中的典型噪声,构建出可靠、可维护的影视索引系统。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

722

2023.08.22

append用法
append用法

append是一个常用的命令行工具,用于将一个文件的内容追加到另一个文件的末尾。想了解更多append用法相关内容,可以阅读本专题下面的文章。

342

2023.10.25

python中append的用法
python中append的用法

在Python中,append()是列表对象的一个方法,用于向列表末尾添加一个元素。想了解更多append的更多内容,可以阅读本专题下面的文章。

1067

2023.11.14

python中append的含义
python中append的含义

本专题整合了python中append的相关内容,阅读专题下面的文章了解更多详细内容。

171

2025.09.12

java学习网站推荐汇总
java学习网站推荐汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

6

2026.01.08

java学习网站汇总
java学习网站汇总

本专题整合了java学习网站相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.01.08

正则表达式 删除
正则表达式 删除

本专题整合了正则表达式删除教程大全,阅读专题下面的文章了解更多详细教程。

20

2026.01.08

java 元空间 永久代
java 元空间 永久代

本专题整合了java中元空间和永久代的区别,阅读专题下面的文章了解更多详细内容。

3

2026.01.08

java 永久代和元空间
java 永久代和元空间

本专题整合了java中元空间和永久代的区别,阅读专题下面的文章了解更多详细内容。

0

2026.01.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.5万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号