我们有一个名为wordlist的文件,其中包含1,876 KB的按字母顺序排列的单词,所有这些单词都超过4个字母,并且在每个新的双字母结构(ab,ac,ad等等)之间包含一个回车符都包含它们之间的回报):
wfile = open("wordlist.txt", "r+")
我想创建一个新文件,其中只包含不是其他较小单词的衍生词。例如,单词列表包含以下单词[“滥用者,滥用者,滥用者,滥用行为,滥用行为等]。创建的新文件应仅保留”滥用“一词,因为它是”最低标准“(如果您在所有这些单词之间。同样,“rodeo”一词将被删除,因为它包含单词rode。
我尝试了这个实现:
def root_words(wordlist):
result = []
base = wordlist[1]
for word in wordlist:
if not word.startswith(base):
result.append(base)
print base
base=word
result.append(base)
return result;
def main():
wordlist = []
wfile = open("wordlist.txt", "r+")
for line in wfile:
wordlist.append(line[:-1])
wordlist = root_words(wordlist)
newfile = open("newwordlist.txt", "r+")
newfile.write(wordlist)
但它总是冻结我的电脑。有解决方案吗
答案 0 :(得分:3)
我会做这样的事情:
def bases(words):
base = next(words)
yield base
for word in words:
if word and not word.startswith(base):
yield word
base = word
def get_bases(infile, outfile):
with open(infile) as f_in:
words = (line.strip() for line in f_in)
with open(outfile, 'w') as f_out:
f_out.writelines(word + '\n' for word in bases(words))
在我相当旧的笔记本电脑上,它在五分之一秒内通过58,000个单词corncob list。它足够大,可以有一个记忆。
$ time python words.py
real 0m0.233s
user 0m0.180s
sys 0m0.012s
它可以在任何地方使用迭代器来轻松实现内存。你可以通过切掉行的末尾而不是使用strip去除换行来提高性能。
另请注意,这取决于您的输入是否已排序且非空。这是所述先决条件的一部分,但我不觉得太不好了;)
答案 1 :(得分:2)
一种可能的改进是使用数据库加载单词并避免在RAM中加载完整的输入文件。另一种选择是在从文件中读取单词时处理单词并写入结果而不将所有内容加载到内存中。
以下示例在读取文件时对其进行处理,而不预先在内存中加载内容。
def root_words(f,out):
result = []
base = f.readline()
for word in f:
if not word.startswith(base):
out.write(base + "\n")
base=word
out.write(base + "\n")
def main():
wfile = open("wordlist.txt", "r+")
newfile = open("newwordlist.txt", "w")
root_words(wfile,newfile)
wfile.close()
newfile.close()
此解决方案的内存复杂性为O(1),因为变量base
是处理文件所需的唯一内容。这可以通过文件按字母顺序排序来完成。
答案 2 :(得分:1)
因为列表是按字母顺序排列的,所以这样做(使用5兆的数据需要0.4秒,所以1.8不应该是一个问题)
res = [" "]
with open("wordlist.txt","r") as f:
for line in f:
tmp = line.strip()
if tmp.startswith(res[-1]):
pass
else:
res.append(tmp)
with open("newlist.txt","w") as f:
f.write('\n'.join(res[1:]))