如何使用元组集和元组列表从现有字典创建嵌套字典

2024-09-24 22:31:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经解析了一个midi文件,并且成功地得到了一个按乐器分解的音符字典。这方面的一个缩略示例如下note_dict,为了本问题的目的,将其截断

我的最终目标是拥有一个嵌套字典,它为我提供曲目名称,然后将每个可能的音符作为键,然后将所有可能的“下一个”音符列表作为值。其目的是将其用作Markov chain in Foxdot,一个用于音乐生成的python接口

它应该看起来像:

{'track1': {note: [note1, note2, note3], note2: [note1, note2, note3]}, 'track2': {note: [note1, note2, note3], note2: [note1, note2, note3]}

以下是我的一个例子:

import itertools 

def pairwise(iterable):
    a, b = itertools.tee(iterable)
    next(b, None)
    return list(zip(a, b))

note_dict = {'Vocal': [-2, -2, -1, -2], 'Guitar': [1, 1, 4, 1, -2, 1]}

note_dict_updated = { track: [{ n for n in notes }, pairwise(notes), notes] for track, notes in note_dict.items() }
print(note_dict_updated)

这给了我以下信息,其中第一组是所有不同的注释,元组列表是(note, next note)的配对,最后一个列表只是按顺序排列的原始注释列表

{'Vocal': [{-2, -1}, [(-2, -2), (-2, -1), (-1, -2)], [-2, -2, -1, -2]], 'Guitar': [{1, 4, -2}, [(1, 1), (1, 4), (4, 1), (1, -2), (-2, 1)], [1, 1, 4, 1, -2, 1]]}

我希望集合的元素充当键,当元组的第一个元素与集合的一个元素匹配时,它将被添加到与键关联的值列表中

基于上面的note_dict,我期望的最终结果是:

{'Vocal': {-2: [-2, -1], -1: [-2]}, 'Guitar': {1: [1, 4, -2], 4: [1], -2: [1]}}

尽管如此,我并没有被锁定在需要使用note_dict_updated的方法中。如果有更聪明的方法从note_dict到我想要的最终结果,我很乐意听到

编辑:我更新了我的问题。对于我的初始示例,first answer有效,但我认为当每个值中的注释列表重叠时会出现问题。希望我更新的预期最终结果会更有帮助


Tags: in元素示例列表字典dictnotenotes
1条回答
网友
1楼 · 发布于 2024-09-24 22:31:49

第一个循环创建具有内部键和相同唯一集的字典的中间字典。然后使用第二个for循环对其进行清洁,如下所示:

输入:

{'Vocal': [-2, -2, -1, -2], 'Guitar': [1, 1, 4, 1]}

输出:

{'Guitar': {1: [1, 4], 4: [1]}, 'Vocal': {-2: [-1, -2], -1: [-2]}}

代码:

#create a new dictionary of dictionary with inner keys and same unique sets

note_dict_updated={}
for key, value in note_dict.iteritems():
    note_dict_updated[key]={}
    for element in set(note_dict[key]):
        note_dict_updated[key][element]=list(set(note_dict[key]))

# remove the values (of not interest) from list values of inner keys 
for key, value in note_dict_updated.iteritems():
    comb=[]
    for lkey, lvalue in note_dict_updated[key].iteritems():
        for val in lvalue:
            if (val,lkey) in comb:
                try:
                    note_dict_updated[key][lkey].remove(lkey)
                except ValueError as e:
                    print ('Issue in key {} for subkey {}'.format(key,lkey))
        for val in lvalue:
            comb.append((lkey,val))

相关问题 更多 >