解析python中的单词列表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析python中的单词列表相关的知识,希望对你有一定的参考价值。

我有一个大约58k字的英语wlist.txt文件,其中一小段摘录如下:

aardvark
aardwolf
aaron
aback
abacus
abaft
abalone
abandon
abandoned
abandonment
abandons
abase
abased
abasement

我想要做的是在列表中搜索程序并查看列表中是否包含单词,如果是,则打印单词。我的问题是,我写的代码将不断返回,不,这个词不在列表中,当我确定它是。我的代码看起来像这样,有人注意到任何错误吗?

match = 'aardvark'
f = 'wlist.txt'
success = False
try:
    for word in open(f):
        if word == match:
            success = True
            break
except IOError:
    print f, "not found!"
if success:
    print "The word has been found with a value of", word
else:
    print "Word not found"

在此先感谢大家!!

答案

正如其他人已经说过的那样,你的问题源于这样一个事实:换行符是你正在阅读的单词的一部分。摆脱这些的最好方法是使用strip()str方法。

此外,您的代码执行太多任务以完成一项简单的任务。您需要做的就是从单词列表中构建一个set,并在集合中查找单词的出现位置。 setlist更适合这项任务,因为检查set中元素的出现要快得多。所以这样的事情应该有效。

try:
    with open('wordlist.txt', 'rU') as infile:
        wordSet = set(line.strip() for line in infile)
except IOError:
       print 'error opening file'

aWord = 'aardvark'

if aWord in wordSet:
    print 'found word', aWord
else:
    print 'word not found'

注意:if aWord in wordSet快得多,不好笑。如果你正在寻找靠近单词列表末尾的单词,那么对于267000单词列表,set的速度快近60000倍。即使你正在寻找第一个单词,它仍然会略微加快。

另一答案

您发布的代码中的问题是迭代打开的文件包括换行符。其他答案处理该问题。

这个答案指出,如果要经常进行搜索,那么策略的效率非常低。

如果搜索将执行多次,那么最好将单词列表存储为Trie,这将启用O(m)查找,其中m是搜索字符串的长度,而构造Trie的复杂性类似于搜索一个单词的单词列表。 Trie可以存储到磁盘(pickled?)以便快速检索。

使用发布的代码在字典中查找单词需要时间与字典的大小成比例,即O(n)。建造Trie的是O(n+C),有一个很大的C,只有在经常搜索的情况下才值得。

我看一下,网上说有几个Python的Trie实现准备尝试。

另一答案

猜猜你可以在python中使用正则表达式(re)来做到这一点。只需使用import re re.search(pattern,source)或re.findall(pattern,source)导入库re。

使用open('wordlist.txt','rU')作为infile:对于infile.readlines()中的item:

if re.search(r'^aardvark',item):
    print('word found')
else:
    print('word not found')
另一答案

这是应该工作的代码

match = 'aardvark'
    f = 'wlist.txt'
    success = False
    try:
        for word in open(f):
            if word.strip() == match: # Change here 
                success = True
                break
    except IOError:
        print f, "not found!"
    if success:
        print "The word has been found with a value of", word
    else:
        print "Word not found"
另一答案

每个人都给你很好的建议如何做到这一点,但你真的需要使用python吗?

grep aardvark wlist.txt

它几乎肯定会破坏任何基于python的速度解决方案。 fgrep可能会更快。

另一答案

对文件对象的迭代包括换行符。

另一答案

尝试用word == match替换word[0:-1] == match以删除word末尾的换行符。

编辑:或者,按照word == match的建议,用word.rstrip() == match替换this question.

另一答案

这是我非常简单的建议:

wordlist = map(str.strip, open("wlist.txt", "r").readlines())
if word in wordlist:
   print "The word has been found with a value of", word
else:
   print "Word not found"
另一答案
file = open(f)
words = set( (line.strip() for line in file.readlines()) )
file.close()

if match in words:
    print "The word has been found with a value of", word
else:
    print "Word not found"
另一答案

您的问题解决起来要简单得多。您还没有意识到您可以以非常适中的成本读取内存中的整个列表 - 您的文件小于1 MB,它非常适合内存。

您的问题的解决方案是将整个事物读入数组并使用标准列表方法来查找成员资格:

# this is the only thing you need to get all the words in memory
words = [w.strip() for w in open("words.txt", "rb").readlines()]

# this is the only thing you need to find wether a word is in the list
print 'aaron' in words
# returns 'True'

# now you can go around many times and ask for membership of any word, 
# or any list of words (use a loop) - the array is already in memory 
# and will stay there until you close the program - it's only 1 mega!

可以说我的解决方案并不聪明,但我认为这是切实可行的 - 过早的优化是所有邪恶的根源,并且通过尝试编写一个聪明的循环,你错过了一个非常简单的方法来解决你的问题非常好(顺便说一下,对于一个6万字的文本文件,对该函数的第一次调用只需不到一秒钟,每次搜索也非常快)。

注意:你不需要set(你不关心一个单词是否重复 - 答案是一样的)。

不要解决错误的问题!

PS。很多人似乎认为58k字是“很多” - 它是(58 +平均长度)kB(如果每个字大约10个字母,那么是580 kB - 大约半个兆字节)。当我听到人们说你不应该在记忆中打开它时,我想知道他们是如何打开他们的照片的!这是一个需要打破的范例。人们会声称“但你的计划并不健全,因为如果这个名单变成1亿千万行,它就会破裂”,这在英语将增加10个数量级的词​​汇世界中是公平的。我们经常忘记一般意味着您的域名。

编辑:根据@Chinmay评论,使用列表上的集合会产生显着的访问后果。使用58K单词列表,我运行了两个1000次访问练习:listset(访问时间,以微秒为单位):

container    min    max   mean
list           3   1646  724.4
set            1     31    1.6

因此,正如@Chinmay指出的那样,一组的平均访问时间几乎要小三个数量级。如果您多次访问这些单词(可能是您),这可能会有所不同。

所以,我修改并修改代码:

# create a set of words
words = set(w.strip() for w in open('file.txt').readlines())

# test access using the `in` operator, as :
'aaron' in words
# will return True

我的观点仍然存在:解决此问题的方法比创建class以实现成员资格运算符要简单得多。

另一答案
class WordMatcher(object):
    @classmethod
    def fromFile(cls, fname):
        with open(fname) as inf:
            return cls(inf)

    def __init__(self, words):
        super(WordMatcher,self).__init__()
        self.words = set(word.strip().lower() for word in words)

    def __contains__(self, word):
        return word.strip().lower() in self.words

    def goodWords(self, lst):
        _sw = self.words
        for word in lst:
            word = word.strip().lower()
            if word in _sw:
                yield word

wordlist = WordMatcher.fromFile('wordlist.txt')

'abase' in wordlist   # -> True
list(wordlist.goodWords(['Abandon', 'abased\n', 'xyzzy']))  # -> ['abandon','abased']

以上是关于解析python中的单词列表的主要内容,如果未能解决你的问题,请参考以下文章

在Python中随机反转列表列表中的一半单词

列表解析

python中的单词聚类列表

自动更正python列表中的单词

如何将一列中的单词拆分然后在Python中将单词整合在一起,即二维列表到一维列表?

删除列表中包含部分单词的 Python 列表中的元素