Python3-具有大列表的高效查找

Python3-具有大列表的高效查找,python,nltk,Python,Nltk,我正在使用NLTK制作自己的Rymer is Python。CMU dict有超过130000个条目,格式如下: [['griffon', ['G', 'R', 'IH1', 'F', 'AH0', 'N']], ['griffy', ['G', 'R', 'IH1', 'F', 'IY0']], ['grigas', ['G', 'R', 'AY1', 'G', 'AH0', 'Z']]] 这些是单词、发音(发音)对。我操纵叉(可能把“G”换成“T”)并检查这是否是一个单词。我通过使用此

我正在使用NLTK制作自己的Rymer is Python。CMU dict有超过130000个条目,格式如下:

[['griffon', ['G', 'R', 'IH1', 'F', 'AH0', 'N']],
 ['griffy', ['G', 'R', 'IH1', 'F', 'IY0']],
 ['grigas', ['G', 'R', 'AY1', 'G', 'AH0', 'Z']]]
这些是单词、发音(发音)对。我操纵叉(可能把“G”换成“T”)并检查这是否是一个单词。我通过使用此函数来完成此操作:

all_word_prons=get_word_pron_pairs_in_cmu_dict()
def pron_是一个单词(发音):
对于word,在所有单词中使用pron:
如果发音==pron:
返回真值
其他:
返回错误
all_word_prons是一个10mb的Python Pickle文件,包含所有130k条目

如果我执行这个查找1000次,大约需要23秒,考虑到这个任务,这不是很糟糕,但必须有一个更好的算法。我见过有人在其他主题上推荐对分集,但这些都适用于简单的字符串查找。这或多或少是检查列表是否相等,而不是字符串

我确实实现了一些树状结构,其中包含如下数据(使用上面的示例):

出于某种原因,这比简单地迭代要花费更长的时间。也许我的实现是错误的。如果你好奇:

def build_fast_id_tree():
从nltk.corpus导入cmudit
entries=cmudict.entries()
idict={}
对于条目中的条目:
单词、发音=词条
idict_级别=idict
对于syl的发音:
如果syl不在idict_级别:
idict_级别[syl]={}
idict_级别=idict_级别[syl]
idict_级别[0]=字
返回idict
def get_fast_id_tree():
filename=“fast_idict_tree.pickle”
如果os.path.isfile(文件名):
list=pickle.load(打开(文件名为“rb”))
其他:
列表=构建快速索引树()
pickle.dump(列表,打开(文件名,“wb”))
返回列表
快速索引树(syls)中的def查找:
idict=get_fast_idict_tree()
对于syl中的syl:
如果syl不在idict中:
返回错误
idict=idict[syl]
如果idict else中的0为False,则返回idict[0]
TL:DR
2015年在Python3中进行此类查找(匹配列表)的最快方法是什么?

您是否考虑过使用此处概述的Python列表理解

在某些情况下,列表理解可能比普通for循环快,但它仍然执行字节码级别的循环。如果您不确定我的意思,请检查以下线程:


也许值得一试,看看这是否会更快。

如果我理解正确,您需要检查数据集中是否有一些
发音。从您的第一个代码块开始,您似乎并不关心匹配来自哪个
word

因此,我认为我们可以:

pron_set = {tuple(pron) for word, pron in all_word_prons}
# do something to get a list of pronunciations to check
for pronunciation in pronunciation_list:
    if tuple(pronunciation) in pron_set:
        print('pronunctiation')
我们从
tuple
s构造
pron\u集
,因为
list
s不可散列(并且不能用作集成员)


集合查找应该比遍历列表快得多。我建议您熟悉以下内容:;你永远不知道什么时候
deque
会为你节省很多时间。

有没有什么特别的原因让你不把发音转换成
元组(这样你就可以对它们进行散列),然后把它们扔到
集合中?或者是一个
dict
,如果你还想把它们映射到原来的单词。换句话说,这只是一个?不。完全正确。我想我没想到字典会快得多。我错了。它们的速度要快得多(1000次查找不到1秒…)。将发音转换为元组,然后将其作为键,并使用.get(发音,False)执行某种错误报告。工作起来很有魅力。谢谢
pron_set = {tuple(pron) for word, pron in all_word_prons}
# do something to get a list of pronunciations to check
for pronunciation in pronunciation_list:
    if tuple(pronunciation) in pron_set:
        print('pronunctiation')