将最大值写入字典而不覆盖

时间:2013-02-22 12:34:16

标签: python dictionary for-loop

我有一个包含翻译概率P(c | e)的双语词典(“概率”)。这是给定特定英语单词e的概率,翻译将是特定的中文单词c。字典键如下所示:probabilities[chinese_word + " | " + english_word]

我还有一个中文句子的语料库(“bitext”)与他们的英语翻译一致。现在,对于每对句子,对于每个中文单词i,我想循环遍历所有英语单词j并选择P(c_i | e_j)最高的单词。我这样做是通过将变量argmax定义为0,并在概率相同或更高时更新此变量。

这是问题:一些c | e组合具有完全相同的翻译概率。但是,由于字典键必须是唯一的,我的代码只存储它看到的最后一个c | e组合。如果它们共享最高的翻译概率,我希望它能够存储几个c | e组合。我该怎么做?

alignments = {}    

for k in range(1, number_of_sent+1):

    sentences = bitext[k-1]
    chinese_sent = sentences[0]
    english_sent = sentences[1]

    for i in range(len(chinese_sent)):
        argmax = 0
        for j in range(len(english_sent)):
            if probabilities[chinese_sent[i] + " | " + english_sent[j]] >= argmax:
                argmax = probabilities[chinese_sent[i] + " | " + english_sent[j]]
                alignments[k, chinese_sent[i]] = english_sent[j]

4 个答案:

答案 0 :(得分:3)

如果您需要为每个键存储多个值,则“对齐”字典必须存储某种类型的集合,例如列表。例如:

from collections import defaultdict

alignments = defauldict(list)

...
[the remainder of your code]
... 

alignments[k, chinese_sent[i]].append(english_sent[j])

顺便说一句,两项更改会让您的代码更清晰:

  1. chinese_sent和english发送的是iterables,您不需要索引,因此您不需要在循环中使用范围。

  2. 您可以使用元组而不是字符串作为概率字典键。

  3. 您的代码将成为:

    from collections import defaultdict
    
    alignments = defauldict(list)
    
    for k in range(1, number_of_sent+1):
    
        sentences = bitext[k-1]
        chinese_sent = sentences[0]
        english_sent = sentences[1]
    
        for cs in chinese_sent:
            argmax = 0
            for es in english_sent:
                if probabilities[cs,es] >= argmax:
                    argmax = probabilities[cs,es]
                    alignments[k, cs].append(es)
    

答案 1 :(得分:1)

尝试将密钥与列表相关联,而不是存储单个值:

alignments[k, chinese_sent[i]].append(english_sent[j])

答案 2 :(得分:0)

您可以将字典的值转换为列表而不是单个值,即具有列表字典。

答案 3 :(得分:0)

alignments [k,chinese_sent [i]]应该是一个列表或数组,如果你看到当前的vaue更高,那么你将它设置为一个新的列表或数组并存储概率并更新argmax。如果它相同,那么你向该列表添加一个新值。