2013-05-29 31 views
6

dizelerinde 2 GB'lık bir listede olup olmadığını kontrol edin ['Question','Q1','Q2','Q3','Ans1','Format','links',...] dizelerinin bir listesini içeren 2 GB büyük bir dosyam var (A.txt).Bir dizenin python

Şimdi başka daha büyük bir dosya (1TB) 2 pozisyonunda yukarıda belirtilen dizeleri içeren vardır:

Çıktı:

a, Question, b 
The, quiz, is 
This, Q1, Answer 
Here, Ans1, is 
King1, links, King2 
programming,language,drupal, 
..... 

Kimin ikinci pozisyon listesindeki dizeleri içeren satırları korumak istiyorsanız A.txt numaralı dosyada saklanır.

a, Question, b 
This, Q1, Answer 
Here, Ans1, is 
King1, links, King2 

Ben dosyada listenin uzunluğu (a.txt) 100..using 'olduğunda bunu nasıl biliyorum: Ben aşağıda belirtilen hatlar (başka dosyada mağaza) korumak istiyorsanız, olduğu herhangi bir'. Ama dosyadaki listenin uzunluğu (A.txt) 2 GB olduğunda, bunun üzerine nasıl gitmem gerektiğini anlamıyorum.

cevap

8

Bir liste kullanmayın; bunun yerine bir set kullanın.

kümesi içine ilk dosyayı okuyun: kelimelerin

with open('A.txt') as file_a: 
    words = {line.strip() for line in file_a} 

0,5 GB kadar bir dizi saklamak için değil olmasıdır. çizgiler kelime virgülle ayrılmış olan, belki de csv modülü kullanılarak

if second_word in words: 
    # .... 

Açık hattı ile ikinci dosya ve yöntem, aynı hat:

Artık O'da words karşı (1) sabit bir zaman test edebilir.

Daha büyük bir kelime grubu için bunun yerine bir veritabanı kullanın; Python sqlite3 kütüphane ile gelir:

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(),)) 
buna karşı

sonra testi:

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(): 
     # .... 

Hatta burada bir :memory: veritabanını kullanmak da, SQLite sen dolduruyor başladığınızda geçici dosyalarda veri depolamak kadar akıllıdır bellek. :memory: bağlantısı temelde sadece bir geçici, bir defaya mahsus veritabanıdır. Kelimeler veritabanını yeniden kullanmak istiyorsanız gerçek bir dosya yolunu da kullanabilirsiniz.

+1

0,5gb'nin bir düzenleme içinde 2gb'ye atladığı anlaşılıyor ... –

+0

@JonClements: Fallback option, sqlite. –

+0

Gerçekten gerekli değil ama sorgu IN/ANY veya EXISTS olarak yeniden yazılabilir - ya da güzel bir şekilde işe yarayacak bir redis veya benzer bir sunucu varsa ... –

1

Martijn Pieters numaralı yanıtla başlayın. Çok yavaşsa, veritabanınızdaki kullanma sayısını azaltmak için listenizdeki herhangi bir sözcükle eşleşmeyecek satırları eleyerek bir Bloom Filter kullanabilirsiniz. Python, hash function dahili bir yapıdadır ve karmaşımlardan birini filtre tablasına yerleştirebilir ve başkalarını arayabilirsin.

+0

+1 Yardımınız için teşekkürler –

İlgili konular