
本文介绍如何使用 Python 的 itertools.combinations 高效查找视频片段时长之和恰好为 90 秒的所有三元组,并准确返回对应的片段名称(而非原始时长数值),避免索引错位与数据不匹配问题。
本文介绍如何使用 python 的 `itertools.combinations` 高效查找视频片段时长之和恰好为 90 秒的所有三元组,并准确返回对应的片段名称(而非原始时长数值),避免索引错位与数据不匹配问题。
在视频剪辑自动化或广告位编排等场景中,常需从一组带有时长信息的素材中筛选出若干片段,使其总时长严格满足目标值(如 90 秒)。若仅对时长列表调用 combinations,虽可快速得到满足条件的数值组合,但会丢失与原始片段名称的映射关系——这正是原代码中 enumerate(spot_dur) 与 result 错位导致输出混乱的根本原因。
正确做法是:直接对 (名称, 时长) 元组列表进行组合迭代,并在判断条件中提取时长分量求和,同时在结果中提取名称分量构造最终元组。以下是完整、健壮的实现:
from itertools import combinations
spots = ("clip1", "clip2", "clip3", "clip4", "clip5", "clip6", "clip7", "clip8", "clip9", "clip10")
durations = (30, 15, 5, 15, 30, 15, 15, 60, 25, 60)
spot_dur = list(zip(spots, durations)) # [('clip1', 30), ('clip2', 15), ...]
def find_triplets(spot_dur, target):
triplets = []
for combo in combinations(spot_dur, 3):
if sum(duration for _, duration in combo) == target: # 解构提取时长
clips = tuple(clip for clip, _ in combo) # 提取对应片段名
triplets.append(clips)
return triplets
target = 90
result_clips = find_triplets(spot_dur, target)
for triplet in result_clips:
print(triplet)运行后将输出类似:
('clip1', 'clip2', 'clip8')
('clip1', 'clip4', 'clip8')
('clip1', 'clip6', 'clip8')
('clip2', 'clip4', 'clip8')
...✅ 关键优势:
- 每个三元组严格对应原始
spot_dur中的真实元素,无索引偏移风险; - 使用解构赋值
(_, duration)和(clip, _)提升可读性与健壮性; - 返回纯名称元组,便于后续日志记录、文件批量处理或 UI 展示。
⚠️ 注意事项:
- 若存在重复时长(如多个
15),不同位置的clip2、clip4、clip6会被视为独立有效项,符合业务逻辑; - 如需去重(例如忽略顺序差异,
(a,b,c)与(b,a,c)视为同一解),可在添加前对clips排序再转为frozenset或tuple(sorted(...)); - 对于大规模数据(>1000 个片段),建议改用动态规划或双指针优化,避免
O(n³)组合开销。
通过将“组合—过滤—投影”逻辑统一在 spot_dur 上完成,我们既保持了代码简洁性,又确保了语义准确性——这才是面向真实数据结构的 Pythonic 解法。

















