我有一个2 GB的大文件(A.txt
),其中包含字符串列表['Question','Q1','Q2','Q3','Ans1','Format','links',...]
。
现在我有另一个更大的文件(1TB),其中包含第二个位置的上述字符串:
输出:
a, Question, b
The, quiz, is
This, Q1, Answer
Here, Ans1, is
King1, links, King2
programming,language,drupal,
.....
我想保留第二个位置包含存储在文件A.txt
中的列表中的字符串的行。也就是说,我想保留(存储在另一个文件中)下面提到的行:
a, Question, b
This, Q1, Answer
Here, Ans1, is
King1, links, King2
我知道当文件(A.txt)中的列表长度为100时使用“任何”时如何执行此操作。但是当文件(A.txt)中的列表长度为2 GB时,我不知道应该如何处理它。
答案 0 :(得分:8)
不要使用列表;改为使用集合。
将第一个文件读入一组:
with open('A.txt') as file_a:
words = {line.strip() for line in file_a}
0.5 GB的单词
现在你可以在O(1)常数时间内对words
进行测试:
if second_word in words:
# ....
打开第二个文件并逐行处理,如果行字以逗号分隔,可能使用csv
模块。
对于更大的单词集,请改用数据库; Python附带sqlite3
库:
import sqlite3
conn = sqlite3.connect(':memory:')
conn.execute('CREATE TABLE words (word UNIQUE)')
with open('A.txt') as file_a, conn:
cursor = conn.cursor()
for line in file_a:
cursor.execute('INSERT OR IGNORE INTO words VALUES (?)', (line.strip(),))
然后对此进行测试:
cursor = conn.cursor()
for line in second_file:
second_word = hand_waving
cursor.execute('SELECT 1 from words where word=?', (second_word,))
if cursor.fetchone():
# ....
即使我在这里使用:memory:
数据库,SQLite也足够智能,可以在您开始填充内存时将数据存储在临时文件中。 :memory:
连接基本上只是一个临时的一次性数据库。如果要重新使用单词database,也可以使用真实的文件路径。
答案 1 :(得分:1)
从Martijn Pieters开始回答。如果这太慢,您可以使用Bloom Filter来减少使用数据库的次数,方法是删除无法匹配列表中任何单词的行。 Python附带了一个内置的hash
function,您可以将其用于过滤表中的一个哈希值,并且您可以查找任意数量的其他值。