解析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
,并在集合中查找单词的出现位置。 set
比list
更适合这项任务,因为检查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次访问练习:list
和set
(访问时间,以微秒为单位):
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中的单词列表的主要内容,如果未能解决你的问题,请参考以下文章