2010-10-22 15 views
6

Metin yaklaşık 22.000 satırdır ve yaklaşık 3,5 MB'dir. İçinde çok sayıda yinelenen çizgi var. Sadece yinelenen satırları ve ayrıca gerekli olmayan belirli dizeleri içeren bazı satırları kaldırmak istiyorum.Python kullanarak bir txt dosyasında (ve ayrıca belirli dizeler içeren bazı satırlarda) yinelenen satırları çıkarmanın en hızlı yolu nedir?

Yolum, readlines() yöntemini kullanarak dosyayı büyük bir listeye okumaktır, sonra read() yöntemini kullanarak dosyayı büyük bir dize olarak okumaktır. Listeyi yineleyin, olayı sayın, satırı "" (boş dize) ile değiştirin. İşi bitirmem 10 dakikamı aldı?

Bunu yapmanın hızlı bir yolu var mı?

Çok teşekkürler!

+2

Python şartı var mı:

>>> seq = ["OK", "bad text2", "OK", "Also OK"] >>> print "\n".join(remove_duplicates(ifilter(is_line_ok, seq))) OK Also OK 

Bu yöntem dosyaları dahil dizeleri döndürür herhangi iterable çalışır? Unix'te 'sort | uniq | grep -v 'badstring \ | çöp' komut satırından. –

+0

"Olay sayısı" ile ne demek istiyorsun? Kaç tane kopyası olduğunu bilmek ister misiniz? Tamamen veya her bir kopya grubu için mi? –

+0

Eh, Unix/Linux hakkında fazla bir şey bilmiyorum, bu yüzden winxp ile koymak zorunda kaldım ... – Shane

cevap

3

Neredeyse her zaman jeneratörler kullanarak dosya işleme yapıyorum. Bu, hızlı, kolay değiştirilebilen ve test edilmesi kolay bir kod yapar.

def remove_duplicates(seq): 
    found = set() 
    for item in seq: 
     if item in found: 
      continue 
     found.add(item) 
     yield item 

İşe yarıyor:

Birincisi, çiftleri kaldıran bir jeneratörü inşa?

Görünüşe göre. Ardından, bir satırın tamam olup olmadığını söyleyen bir işlev oluşturun:

def is_line_ok(line): 
    if "bad text1" in line: 
     return False 
    if "bad text2" in line: 
     return False 
    return True 

Bu işe yarar mı?

>>> is_line_ok("this line contains bad text2.") 
False 
>>> is_line_ok("this line's ok.") 
True 
>>> 

Şimdi biz bizim işlevi ile remove_duplicates ve itertools.ifilter kullanabilirsiniz:

with open(input_file, 'r') as f_in: 
    with open(output_file, 'w') as f_out: 
     f_out.writelines(remove_duplicates(ifilter(is_line_ok, f_in))) 
+0

Ayrıntılar için çok teşekkürler! – Shane

0
goodLines = set() 
badString = 'bad string' 

with open(inFilename, 'r') as f: 
    for line in f: 
     if badString not in line: 
      goodLines.add(line) 

# and let's output these lines (sorted, unique) in another file... 

with open(outFilename, 'w') as f: 
    f.writelines(sorted(goodLines)) 
3
list(set(line for line in file.readlines() 
     if 'badstring' not in line 
     and 'garbage' not in line)) 

Ayrıca regex hızlı bir katından daha not in testler olabilir.

+0

(önemsiz düzenleme gerekli, üzgünüm, ama aksi takdirde SO benim oy vermeme izin vermemişti) –

+3

orada 'readlines' gerekmez – SilentGhost

+0

Eh, hala biraz kafam karıştı. Nasıl çalıştığını açıklar mısınız lütfen? Teşekkürler! – Shane

İlgili konular