从嵌套字典中访问值

1 投票
4 回答
1244 浏览
提问于 2025-04-17 02:32

我正在尝试创建一个列表,里面包含输入的内容和它们对应的值,这些值是从一个全局的嵌套字典中获取的。以下是我的代码:

import sys

param_values = {
            'vowels':{
            'aa' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)],     
            'ae' : [(-1,-1),   (-1,-1),    (0.1,0.8), (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'ah' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'ao' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.2,1.0),   (-1,-1)], 
            'eh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'er' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.15,0.7),  (-1,-1)], 
            'ey' : [(-1,-1),   (-1,-1),    (0.3,1.0), (-1,-1),   (0.1,0.5),   (-1,-1)],
            'ih' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'iy' : [(-1,-1),   (-1,-1),    (0.2,1.0), (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'uh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)], 
            'uw' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)],   
            'o'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.4,1.0)]    
            },
            'consonants':{
            'b'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'ch' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'd'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'dh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.35),  (-1,-1)], 
            'dx' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.35),  (-1,-1)], 
            'f'  : [(0.3,1.0), (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (-1,-1)], 
            'g'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'hh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'jh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'k'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'l'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'm'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'n'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            'ng' : [(-1,-1),   (0.1,1.0),  (-1,-1),   (-1,-1),   (0.0,0.0),   (-1,-1)], 
            'p'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'r'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            's'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)],
            'sh' : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            't'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'th' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'v'  : [(0.3,1.0), (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (-1,-1)], 
            'w'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)], 
            'y'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.6),   (-1,-1)],  
            'z'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            'zh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.6),   (-1,-1)] 
             }                         
            }

diphthong = { 
         'aw' : ['ao' , 'uw'],
         'ay' : ['ao' , 'ih'],
         'ow' : ['o' , 'aa'],
         'oy' : ['o' , 'ih']
        }   

print "Usage :python co.py phonemeFile"

def coart(phonemeFile):
""" Function for generating parameter values from the global list """
phonemeList = []
with open("syllabifiedPhonemes.txt", "r") as pFile :
    for line in pFile :
        l = line.split()
        for phoneme in l : 
            next_phoneme = diphthong.get(phoneme)
            if next_phoneme is None :
                # exploring the dict param_values extracting each nested dict
                for group in param_values.keys() : # 'group' refers to vowels or consonants
                    # iterate over each nested dict 
                    for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
                        phonemeList.append((phones, param_values.get(param_values[group][phones])))
            else : 
                for group in param_values.keys() : # 'group' refers to vowels or consonants
                    for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
                        phonemeList.extend([(phones, param_values.get(param_values[group][phones])) for phoneme in next_phoneme])

        print "New List"
        print '\n'.join(str(l) for l in phonemeList)

输入文件 syllabifiedPhonemes.txt 的内容如下:

s aa ' m ih ' k l eh k ' t aa ' n ih t ' g eh l ' v ae ' n ih ' k aa ' p l ay k

我觉得 if-else 语句写得不对。于是我遇到了以下错误:

Traceback (most recent call last):
  File "co.py", line 189, in <module>
coart("syllabifiedPhonemes.txt")
  File "co.py", line 160, in coart
phonemeList.append((phones, param_values.get(param_values[group][phones])))
TypeError: unhashable type: 'list'

我把 if-else 语句改成了下面这样,错误消除了。

if next_phoneme is None :
    # exploring the dict param_values extracting each nested dict
    for group in param_values.keys() : # 'group' refers to vowels or consonants
        # iterate over each nested dict 
        for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
            phonemeList.append((phones, param_values[group][phones]))
else : 
    for group in param_values.keys() : # 'group' refers to vowels or consonants
        for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
            phonemeList.extend([(phones, param_values[group][phones]) for phoneme in next_phoneme])

但是现在我得到的输出是一个很大的列表,我猜程序在字典中循环了很多次,结果一次又一次地打印出整个字典,而不是只显示给定输入的值。有人能告诉我哪里出错了吗?谢谢。

4 个回答

1

这里不应该使用 param_values.get,因为你已经用 param_values[...] 来读取这个值了。

也就是说,不要这样写:

param_values.get(param_values[group][phones])

应该这样写:

param_values[group][phones]

如果你想要在键不存在的情况下使用一个默认值,可以用 get 来代替(而不是额外加上) [...],但在这个情况下其实没必要。

1

这是对你下面这个新代码版本片段的回复:

if next_phoneme is None :
    # exploring the dict param_values extracting each nested dict
    for group in param_values.keys() : # 'group' refers to vowels or consonants
        # iterate over each nested dict 
        for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
            phonemeList.append((phones, param_values[group][phones]))
else : 
    for group in param_values.keys() : # 'group' refers to vowels or consonants
        for phones in param_values[group].keys() : # 'phones' refers to the phonemes present inside each group 
            phonemeList.extend([(phones, param_values[group][phones]) for phoneme in next_phoneme])

如果我理解得没错,你的目标是这样的,我觉得你想要的可以写成:

next_phonemes = diphthong.get(phoneme, [phoneme])
for next_phoneme in next_phonemes:
    # exploring the dict param_values extracting each nested dict
    for group_val in param_values.itervalues(): # 'group_val' refers to values associated to vowels or consonants
        if next_phoneme in group_val:
            phonemeList.append((next_phoneme, group_val[next_phoneme])
            break # Once we found the next phoneme, no need to look further
1

试试这样做。这种方法简单多了,而且效率也更高(我觉得)

import sys

param_values = {
            'aa' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)],     
            'ae' : [(-1,-1),   (-1,-1),    (0.1,0.8), (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'ah' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'ao' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.2,1.0),   (-1,-1)], 
            'eh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,1.0),   (-1,-1)], 
            'er' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.15,0.7),  (-1,-1)], 
            'ey' : [(-1,-1),   (-1,-1),    (0.3,1.0), (-1,-1),   (0.1,0.5),   (-1,-1)],
            'ih' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'iy' : [(-1,-1),   (-1,-1),    (0.2,1.0), (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'uh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)], 
            'uw' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)],   
            'o'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.4,1.0)] ,   
            'b'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'ch' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'd'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'dh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.35),  (-1,-1)], 
            'dx' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.35),  (-1,-1)], 
            'f'  : [(0.3,1.0), (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (-1,-1)], 
            'g'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'hh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'jh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'k'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'l'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'm'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'n'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            'ng' : [(-1,-1),   (0.1,1.0),  (-1,-1),   (-1,-1),   (0.0,0.0),   (-1,-1)], 
            'p'  : [(-1,-1),   (0.0,0.0),  (-1,-1),   (-1,-1),   (0.1,0.8),   (-1,-1)], 
            'r'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            's'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)],
            'sh' : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            't'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'th' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.4),   (-1,-1)], 
            'v'  : [(0.3,1.0), (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (-1,-1)], 
            'w'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (-1,-1),     (0.1,1.0)], 
            'y'  : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.6),   (-1,-1)],  
            'z'  : [(-1,-1),   (0.1,1.0),  (-1,-1),   (0.3,1.0), (0.0,0.0),   (-1,-1)], 
            'zh' : [(-1,-1),   (-1,-1),    (-1,-1),   (-1,-1),   (0.1,0.6),   (-1,-1)]                         
            }

diphthong = { 
         'aw' : ['ao' , 'uw'],
         'ay' : ['ao' , 'ih'],
         'ow' : ['o' , 'aa'],
         'oy' : ['o' , 'ih']
        }   


phonemeList = []
with open("syllabifiedPhonemes.txt", "r") as pFile :
    for line in pFile :
        l = line.split()
        for phoneme in l : 
            if phoneme != "'":
                next_phoneme = diphthong.get(phoneme)
                if next_phoneme is None :
                    # exploring the dict param_values extracting each nested dict
                    phonemeList.append((phoneme, param_values[phoneme]))
                else : 
                    phonemeList.extend([(phoneme, param_values[phoneme]) for phoneme in next_phoneme])

        print "New List"
        print '\n'.join(str(l) for l in phonemeList)

如果你需要辅音和元音的信息,最好把它存放在其他地方。把它放在这里会让代码变得太复杂。

注意:我把测试用的函数去掉了。显然,你应该把它放回你的代码里;)

撰写回答