首先,我知道关于 SO 的 Python 内存错误问题的数量,但到目前为止,没有一个与我的用例相匹配。
我目前正在尝试解析一堆文本文件(约 6k 文件,约 30 GB)并存储每个唯一的单词。是的,我正在建立一个单词表,不,我不打算用它做坏事,这是为了大学。
我将找到的单词列表实现为一个集合(使用创建words = set([])
,使用words.add(word)
),我只是将每个找到的单词添加到其中,考虑到集合机制应该删除所有重复项。
这意味着我需要永久访问整个集合才能使其正常工作(或者至少我看不到其他选择,因为必须在每次插入时检查整个列表的重复项)。
现在,MemoryError
当它使用大约 3.4 GB 的 RAM 时,我正在运行大约 25%。我使用的是 32 位 Linux,所以我知道这个限制来自哪里,而我的电脑只有 4 Gigs 的 RAM,所以即使是 64 位也无济于事。
我知道复杂性可能很糟糕(每次插入可能 O(n),虽然我不知道 Python 集是如何实现的(树?)),但它仍然(可能)更快并且(肯定)内存效率更高而不是将每个单词添加到原始列表并随后删除重复项。
有什么办法可以让它运行吗?我预计大约 6-10 GB 的唯一词,所以使用我当前的 RAM 是不可能的,并且升级我的 RAM 目前是不可能的(一旦我开始让这个脚本在大量文件上松散,就不能很好地扩展) .
我目前唯一的想法是在磁盘上缓存(这会进一步减慢进程),或者将临时集写入磁盘并在之后合并它们,这将花费更多时间,而且复杂性确实很可怕。是否有一种解决方案不会导致可怕的运行时间?
作为记录,这是我的全部来源。由于它仅供个人使用,它非常可怕,但你明白了。
import os
import sys
words=set([])
lastperc = 0
current = 1
argl = 0
print "Searching for .txt-Files..."
for _,_,f in os.walk("."):
for file in f:
if file.endswith(".txt"):
argl=argl+1
print "Found " + str(argl) + " Files. Beginning parsing process..."
print "0% 50% 100%"
for r,_,f in os.walk("."):
for file in f:
if file.endswith(".txt"):
fobj = open(os.path.join(r,file),"r")
for line in fobj:
line = line.strip()
word, sep, remains = line.partition(" ")
if word != "":
words.add(word)
word, sep, remains = remains.partition(" ")
while sep != "":
words.add(word)
word, sep, remains2 = remains.partition(" ")
remains = remains2
if remains != "":
words.add(remains)
newperc = int(float(current)/argl*100)
if newperc-lastperc > 0:
for i in range(newperc-lastperc):
sys.stdout.write("=")
sys.stdout.flush()
lastperc = newperc
current = current+1
print ""
print "Done. Set contains " + str(len(words)) + " different words. Sorting..."
sorteddic = sorted(words, key=str.lower)
print "Sorted. Writing to File"
print "0% 50% 100%"
lastperc = 0
current = 1
sdicl = len(sorteddic)-1
fobj = open(sys.argv[1],"w")
for element in sorteddic:
fobj.write(element+"\n")
newperc = int(float(current)/sdicl*100)
if newperc-lastperc > 0:
for i in range(newperc-lastperc):
sys.stdout.write("=")
sys.stdout.flush()
lastperc = newperc
current = current+1
print ""
print "Done. Enjoy your wordlist."
感谢您的帮助和想法。