高效的方法,从列表中消除半重复项

3
我有一系列谜题:摩尔斯电码字符串中没有字母或单词之间的空格。 我的计划是进行字典攻击以找到最佳解决方案候选者。 我的武器是Python。
我有一个包含17000个英文单词的列表。我还有一个与谜题主题相关的较小单词列表,如果这些单词出现,则应该得分更高。
因此,在我的脚本最开始生成单词列表时,我使用一组元组列表,形式为(单词,分数乘数)。以下是一个小子集:
[('zoned', 1.0), 
 ('zonely', 1.0), 
 ('zoner', 1.0), 
 ('zones', 1.0), 
 ('zoning', 1.0), 
 ('zoo', 1.0), 
 ('zoom', 1.0), 
 ('zoomed', 1.0), 
 ('zooming', 1.0), 
 ('zooms', 1.0), 
 ('zoos', 1.0), 
 ('ten', 1.0), 
 ('tens', 1.0), 
 ('gnash', 1.0), 
 ('shag', 1.0), 
 ('75th', 2.0), 
 ('seventy', 2.0), 
 ('fifth', 2.0)]

在我解析的文件中,我想要将高价值词汇放在末尾,而不必手动删除文件主体中的任何重复内容。因此,我需要编写一些代码来删除早期元组的第一个值等于后面元组第一个值的情况。
我可以使用暴力方法来实现:
for firstkey, (firstword, firstfactor) in enumerate(wordlist):
    for laterkey, (laterword, laterfactor) in enumerate(wordlist[firstkey+1:]):
        if firstword == laterword:
            del wordlist[firstkey]
            break

但是光是脚本的那一部分就需要将近45秒的时间,而且我这17000个单词还没有完全覆盖整个字典。(那段代码也没有经过测试,所以它可能根本不起作用。)看起来这种方法也不是很Pythonic,尽管我现在刚开始学习Python(并且这个项目是我首次编程)。
有更好的方法吗?我不能使用set(),因为重复的单词是不相等的元组的一部分。我需要重新构造我的数据吗?或者每次运行时都要准备等待整整一分钟?

如果您可以使用==,那么您应该能够使用set。您所说的“重复单词不是100%重复”是什么意思? - Roland Smith
我澄清了那句话。重复的单词是不相等元组的成员。所以,如果我使用 set(),两个单词仍将存在。 - 75th Trombone
很酷的问题,请问你能分享一个链接给我们吗? - Colonel Panic
1个回答

3

我可能误解了问题,但是看起来你可以从元组列表生成一个dict。后面的值会自动覆盖先前的值:

lst = [
    ('foo', 1),
    ('bar', 2),
    ('foo', 10)
]

print dict(lst) # {'foo': 10, 'bar': 2}

这很酷,但这样他不会保留更高的值,只会保留最后一个。 - Netwave
我对此其实没什么问题。在我的情况下,“最后声明的值”并不劣于“最高声明的值”。我希望能够有两种选择,但如果找不到这个答案,这个方案绝对足够满足我的需求。 - 75th Trombone
我认为即使你想要最高的值,使用字典也是有意义的。你不能简单地将元组列表传递给字典构造函数,但一个简单的循环就可以解决问题:for key, value in lst: if value > dct.get(key, 0): dict[key] = value。使用字典可以快速访问先前的值(如果存在)。从collections中使用defaultdict也可以起到同样的作用,消除了使用dict.get的需要。 - Blckknght
是的,我的第一个想法是 max_scores = defaultdict(int) / for word, word_score in word_scores: max_scores[word] = max(max_scores[word], word_score) - DSM
是的,我越想越觉得使用元组是错误的选择。使用字典感觉不太对;我主要关心的是键而不是值。但实际上使用字典似乎是最实用的做法。 - 75th Trombone

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接