まず、SO に関する Python メモリ エラーの質問の量を認識していますが、これまでのところ、私のユース ケースに一致するものはありません。
現在、一連のテキストファイル(〜30 GBの〜6kファイル)を解析し、一意の単語をそれぞれ保存しようとしています。はい、単語リストを作成しています。いいえ、悪いことをするつもりはありません。大学用です。
見つかった単語のリストをセットとして実装しました ( で作成されwords = set([])
、 で使用されwords.add(word)
ます)。セットの仕組みがすべての重複を削除する必要があることを考慮して、見つかったすべての単語をそれに追加するだけです。
これは、これが機能するためにセット全体に永続的にアクセスする必要があることを意味します (または、挿入ごとにリスト全体の重複をチェックする必要があるため、少なくとも代替手段はありません)。
現在、MemoryError
約 3.4 GB の RAM を使用している場合、約 25% に達しています。私は Linux 32 ビットを使用しているので、その制限がどこから来るのかを知っています。また、私の PC には 4 ギガの RAM しかないため、64 ビットでもここでは役に立ちません。
複雑さはおそらくひどいことを知っています(Pythonセットがどのように実装されているか(ツリー?)はわかりませんが、各挿入でおそらくO(n))が、それでも(おそらく)高速で(間違いなく)メモリ効率が高くなります各単語をプリミティブ リストに追加し、後で重複を削除するよりも。
これを実行する方法はありますか?約 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."
あなたの助けとアイデアをありがとう。