2

我有类型 0 的 MIDI 文件,包含只有 269 个元消息的轨道,我想保留标题块和文件末尾的最后一个。

for i, msg in enumerate(mid.tracks[0]):
    if i > 10 or i < len(mid.tracks[0])-1:
        if msg.is_meta:
            mid.tracks[0].pop(i)

上面的代码,没有这样做。事实上,它恰好删除了一半的消息(其中 135 条),它还删除了开头和结尾,我必须运行它几次才能让它接近 10 条元消息!

图书馆

pop([index]) → item -- 删除并返回索引处的项目(默认最后一个)。如果列表为空或索引超出范围,则引发 IndexError。

我也尝试了另一种方法,但同样,每次只删除一半。所以我需要多次运行循环以使其接近我想要的大小:

while len(mid.tracks[0])>16:
    for i, msg in enumerate(mid.tracks[0]):
        if msg.is_meta and hasattr(msg, 'data'): 
            if len(msg.data) == 7:
                mid.tracks[0].remove(msg)

for i, msg in enumerate(mid.tracks[0]):
    if msg.is_meta:
        print(i, msg)

请问我做错了什么?

4

1 回答 1

0

这样的事情可能会更快。请注意,代码可能与您的数据不完全匹配。如果您发布 mid.tracks[0] 的值,我可以为您提供更好的结果。

t = mid.tracks[0] # shorthand to simplify code
keep = t[:10] + t[-1:] # get first ten and last one
# keep only the non-meta ones
result = [msg for msg in keep if not msg.is_meta]

注:根据评论修改。

于 2020-04-19T21:44:39.973 回答