Python 列出字典中以<;开头的所有单词;用户输入>;

Python 列出字典中以<;开头的所有单词;用户输入>;,python,list,dictionary,Python,List,Dictionary,a如何制作一个程序,让用户输入一个字符串,然后程序生成一个以该字符串开头的单词列表 例如: 用户:“abd” 计划:退位,腹部,外展 谢谢 编辑:我正在使用python,但我认为这是一个与语言无关的问题。尝试使用正则表达式搜索您的单词列表,例如/^word/并报告所有匹配项。最好的方法之一是使用有向图存储词典。这需要一点设置,但一旦完成,就可以相当容易地进行您所说的搜索类型 var words = from word in dictionary where word.k

a如何制作一个程序,让用户输入一个字符串,然后程序生成一个以该字符串开头的单词列表

例如:
用户:“abd”
计划:退位,腹部,外展

谢谢



编辑:我正在使用python,但我认为这是一个与语言无关的问题。

尝试使用正则表达式搜索您的单词列表,例如/^word/并报告所有匹配项。

最好的方法之一是使用有向图存储词典。这需要一点设置,但一旦完成,就可以相当容易地进行您所说的搜索类型

var words = from word in dictionary
            where word.key.StartsWith("bla-bla-bla");
            select word;
def main(script, name):
    for word in open("/usr/share/dict/words"):
        if word.startswith(name):
            print word,

if __name__ == "__main__":
    import sys
    main(*sys.argv)
图中的节点对应于word中的一个字母,因此每个节点将有一个传入链接和最多26个(英语)传出链接

您还可以使用一种混合方法,维护包含词典的排序列表,并使用有向图作为词典的索引。然后,您只需在有向图中查找前缀,然后转到词典中的该点,吐出与搜索条件匹配的所有单词。

使用


将单词列表添加到trie中。从根到叶的每个路径都是有效的单词。从根节点到中间节点的路径表示前缀,中间节点的子节点是前缀的有效补全。

如果您确实想提高效率,请使用后缀树或后缀数组

你的问题是后缀树被设计用来处理什么。 甚至还有Python的实现-

如果您需要非常快速,请使用树:

构建一个数组,根据第一个字母将单词拆分为26组,然后根据第二个字母将每个项目拆分为26组,然后再次拆分


因此,如果您的用户键入“abd”,您将查找数组[0][1][3],并获得一个以该开头的所有单词的列表。此时,您的列表应该足够小,可以传递给客户端并使用javascript进行过滤。

如果您在类似debian的机器上

#!/bin/bash
echo -n "Enter a word: "
read input
grep "^$input" /usr/share/dict/words
在我的P200上记录所有的0.040

egrep `read input && echo ^$input` /usr/share/dict/words
哦,我没有看到Python编辑,在Python中也是这样

my_input = raw_input("Enter beginning of word: ")
my_words = open("/usr/share/dict/words").readlines()
my_found_words = [x for x in my_words if x[0:len(my_input)] == my_input]

如果你真的想要速度,可以使用trie/自动机。但是,考虑到单词列表已排序,这将比简单地扫描整个列表更快:

from itertools import takewhile, islice
import bisect

def prefixes(words, pfx):
    return list(
             takewhile(lambda x: x.startswith(pfx), 
                       islice(words, 
                              bisect.bisect_right(words, pfx), 
                              len(words)))

请注意,根据字典的大小,自动机是O(1),而这个算法是O(log(m)),然后是O(n),关于实际以前缀开头的字符串数量,而完整扫描是O(m),n如果字典非常大,我建议使用python文本索引(PyLucene——请注意,我从未使用过lucene的python扩展)搜索将非常高效,您甚至可以返回搜索“分数”


此外,如果你的词典相对静态,你甚至不会经常需要重新编制索引。

不要用火箭筒来消灭苍蝇。使用类似SQLite的简单工具。每种现代语言都有你需要的所有工具,你可以做:

"SELECT word FROM dict WHERE word LIKE "user_entry%"
它闪电般的快,一个婴儿就可以做到。更重要的是它的便携性,持久性和易于维护

Python tuto:


线性扫描速度慢,但前缀树可能是杀伤力过大。保持单词排序并使用二进制搜索是一种快速而简单的折衷方法

import bisect
words = sorted(map(str.strip, open('/usr/share/dict/words')))
def lookup(prefix):
    return words[bisect.bisect_left(words, prefix):bisect.bisect_right(words, prefix+'~')]

>>> lookup('abdicat')
['abdicate', 'abdication', 'abdicative', 'abdicator']
大多数肾盂液 请记住,生成器只能使用一次,因此请将其转换为列表(使用list(word_generator))或使用itertools.tee函数(如果希望多次使用)

最好的方法是: 将其存储到数据库中,并使用SQL查找所需的单词。如果词典中有大量单词,则查找速度会更快,效率也会更高


Python获得了数千个DB API来帮助您完成这项工作;-)

如果您将单词存储在.csv文件中,您可以使用pandas来相当巧妙地解决这个问题,并且在您阅读完之后,如果用户应该能够在每个会话中执行多个搜索,您可以重用已经加载的数据帧

df = pd.read_csv('dictionary.csv')
matching_words = df[0].loc[df[0].str.startswith(user_entry)] 

您可以使用
str.startswith()
。记录到官方文件:

str.startswith(前缀[,开始[,结束]]) 如果字符串以前缀开头,则返回True,否则返回False。前缀也可以是要查找的前缀元组。使用可选开始,测试从该位置开始的字符串。使用可选结束,停止在该位置比较字符串

如下图所示:

user_input = input('Enter something: ')
for word in dictionary:
    if str.startswith(user_input):
        return word

不。我正在想办法完成单手键盘挑战(参见XKCD博客)。我想有一个比重新注册整本字典更好的方法!我在学校没有上CS课,这很公平。我说过你不想在这个问题中对整本词典进行正则化。我想作者的意思是[如果w.startswith(x)]:)是的,尽管我在他编辑之前写下了我的答案。尽管如此,他在python中也能做到这一点:p这很简洁,在这里也可以,因为字典已经分类了-谢谢!基于词典已分类的理由,这里肯定有一个优化。这不是对提供的代码的批评,因为它可能已经足够快了。只是觉得值得一提。是的,但我的答案是先例。后缀树在这里有什么帮助?它们不是被设计成高效地搜索任意子字符串,而不仅仅是前缀吗?子字符串树可以快速告诉您字符串是否包含子字符串。每棵树都有一根绳子。它不是字符串的集合。这将是确定“dom”是否是“腹部”的子字符串的有效方法,但我不知道如何使其适应OP的问题。
user_input = input('Enter something: ')
for word in dictionary:
    if str.startswith(user_input):
        return word