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

如何迭代命名元组列表,按键值过滤分组得到匹配的音频文件组合

问题描述

现有3个存储命名元组的列表,分别对应鼓轨、旋律轨、贝斯轨的音频信息,代码如下:

drumlist = [drums( title='99_drumtrack_1.wav', bpm='99'),
drums( title='95_drumtrack_2.wav', bpm='95'),
drums( title='93_drumtrack_3.wav', bpm='93'),
#etc...
]

melodylist = [melody( title='99_Abmin_melodytrack_1.wav', bpm='99', key='Abmin'),
melody( title='95_Bbmin_melodytrack_2.wav', bpm='95' ,key='Bbmin'),
melody(title='93_Fmaj_melodytrack_3.wav', bpm='93' , key='Fmaj'),
melody(title='92_Gmaj_melodytrack_4.wav', bpm='92' , key='Gmaj')
#etc...
]

basslist = [bass( title='99_Abmin_basstrack_1.wav', bpm='99', key='Abmin'),
bass(title='95_Bbmin_basstrack_2.wav', bpm='95', key='Bbmin'),
bass(title='93_Fmaj_basstrack_3.wav', bpm='93', key='Fmaj')
#etc...
]

需要实现的匹配规则:按bpm匹配,同时旋律、贝斯的key(调性)一致的三个文件分为一组,每组生成sound1(鼓文件名)、sound2(旋律文件名)、sound3(贝斯文件名)三个变量供后续处理,期望输出示例如下:

#interation 1
sound1 = 99_drumtrack_1.wav
sound2 = 99_Abmin_melodytrack_1.wav #KEYNOTE Abmin key for melody matches Abmin key for bass
sound3 = 99_Abmin_basstrack_1.wav #KEYNOTE Abmin key for bass matches Abmin key for melody
#use sound1, sound2 & sound3 variables further

#interation 2
sound1 = 95_drumtrack_2.wav
sound2 = 95_Bbmin_melodytrack_2.wav
sound3 = 95_Bbmin_basstrack_2.wav
#use sound1, sound2 & sound3 variables further

#etc...

当前用嵌套for循环实现缩进层级过多,希望得到更简洁高效的实现方案。

解决方案

推荐用索引映射的方案,完全避免多层嵌套循环,逻辑清晰且效率更高:

# 1. 先构建两个索引字典,把查询复杂度降到O(1)
# 鼓轨按bpm做索引,key为bpm值,value为对应鼓轨文件名
drum_index = {d.bpm: d.title for d in drumlist}
# 贝斯轨按 (bpm, key) 复合条件做索引,key为(bpm, key)元组,value为贝斯文件名
bass_index = {(b.bpm, b.key): b.title for b in basslist}

# 2. 直接遍历旋律轨匹配即可
for idx, melo in enumerate(melodylist, 1):
    # 同时匹配到对应bpm的鼓、对应bpm+key的贝斯才输出
    if melo.bpm in drum_index and (melo.bpm, melo.key) in bass_index:
        sound1 = drum_index[melo.bpm]
        sound2 = melo.title
        sound3 = bass_index[(melo.bpm, melo.key)]
        # 此处直接调用三个变量做后续业务处理即可
        print(f"# iteration {idx}")
        print(f"sound1 = {sound1}")
        print(f"sound2 = {sound2} #KEYNOTE {melo.key} key for melody matches {melo.key} key for bass")
        print(f"sound3 = {sound3} #KEYNOTE {melo.key} key for bass matches {melo.key} key for melody")
        print("# use sound1, sound2 & sound3 variables further\n")

如果存在同个bpm对应多个鼓轨的场景,只需把鼓索引的value改为列表存储即可,调整代码如下:

from collections import defaultdict
drum_index = defaultdict(list)
for d in drumlist:
    drum_index[d.bpm].append(d.title)

# 匹配时遍历对应bpm下的所有鼓轨即可
for idx, melo in enumerate(melodylist, 1):
    if melo.bpm in drum_index and (melo.bpm, melo.key) in bass_index:
        for drum_title in drum_index[melo.bpm]:
            sound1 = drum_title
            sound2 = melo.title
            sound3 = bass_index[(melo.bpm, melo.key)]
            # 后续业务逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:54:03