You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中检查一个字典的值是否部分匹配另一个字典的值(音阶与和弦场景)

解决字典值子集匹配的问题

首先,咱们先说说你遇到的KeyError原因:你用range(len(chords))得到的是一串数字(比如0、1、2...),但字典的键是字符串(比如'minor'、'maj'),直接用数字去访问字典的键自然会报错——字典里根本没有这些数字键呀!

接下来,咱们一步步实现你要的功能:判断和弦的音符列表是否是某个音阶音符列表的子集,然后输出对应的键和值。

核心思路

要判断列表A是否是列表B的子集,最简洁高效的方式是把两个列表转换成集合,然后用集合的issubset()方法来判断(集合天生擅长做这种成员关系判断)。另外,遍历字典的时候,直接用items()方法可以同时拿到键和对应的值,不用再手动处理索引。

完整代码示例

# 定义你的音阶和和弦字典
scales = {'major': ['1', '2', '3', '4', '5', '6', '7'], 
          'harmmaj': ['1', '2', '3', '4', '5', 'b6', '7'], 
          'minor': ['1', '2', 'b3', '4', '5', 'b6', 'b7'], 
          'harmmin': ['1', '2', 'b3', '4', '5', 'b6', '7'], 
          'melmin': ['1', '2', 'b3', '4', '5', '6', '7']}

chords = {'minor': ['1', 'b3', '5'], 
          'm6': ['1', 'b3', '5', '6'], 
          'm7': ['1', 'b3', '5', 'b7'], 
          'sus2': ['1', '2', '5'], 
          'sus4': ['1', '4', '5'], 
          'maj': ['1', '3', '5'], 
          'maj6': ['1', '3', '5', '6'], 
          'maj7': ['1', '3', '5', '7'], 
          'dom7': ['1', '3', '5', 'b7'], 
          'dim': ['1', 'b3', 'b5'], 
          'dim7': ['1', 'b3', 'b5', 'b7'], 
          'aug': ['1', '3', '#5'], 
          'aug7': ['1', '3', '#5', 'b7']}

# 遍历每个和弦的名称和对应的音符列表
for chord_name, chord_notes in chords.items():
    # 把和弦音符转成集合,方便后续判断
    chord_set = set(chord_notes)
    # 遍历每个音阶的名称和对应的音符列表
    for scale_name, scale_notes in scales.items():
        scale_set = set(scale_notes)
        # 判断和弦集合是否是音阶集合的子集
        if chord_set.issubset(scale_set):
            print(f"和弦「{chord_name}」({chord_notes}) 是音阶「{scale_name}」({scale_notes}) 的子集")

代码解释

  1. dict.items():这个方法会返回字典中所有的键值对,比如对于chords,每次循环会拿到('minor', ['1', 'b3', '5'])这样的元组,直接解构为chord_name和chord_notes,非常方便。
  2. 集合转换:set(chord_notes)把列表转成集合,集合的issubset()方法会快速判断所有元素是否都在另一个集合里,比你手动写循环判断要简洁高效得多。
  3. 输出格式:用f-string格式化输出,让结果更清晰易读。

优化小技巧(可选)

如果字典里的元素很多,我们可以提前把所有音阶的集合存起来,避免每次循环都重复转换:

# 提前预存音阶的集合
scale_sets = {name: set(notes) for name, notes in scales.items()}

for chord_name, chord_notes in chords.items():
    chord_set = set(chord_notes)
    for scale_name, scale_set in scale_sets.items():
        if chord_set.issubset(scale_set):
            print(f"和弦「{chord_name}」({chord_notes}) 是音阶「{scale_name}」({scales[scale_name]}) 的子集")

这样可以减少重复的集合转换操作,提升程序运行效率~

内容的提问来源于stack exchange,提问作者Intheguy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 06:32:29