检查字符串是否在python中的2 GB字符串列表中

时间:2013-05-29 20:28:34

标签: python

我有一个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时,我不知道应该如何处理它。

2 个答案:

答案 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,您可以将其用于过滤表中的一个哈希值,并且您可以查找任意数量的其他值。