2010-05-23 29 views
18

Bir csv DictReader nesnesine (Python 3.1 kullanarak) sahibim, ancak okuyucusunda bulunan satır/satır sayısını bilmek istiyorum. aşağıdaki gibi gibi bir şey ...Satır sayısı satır sayısı csv.DictReader

myreader = csv.DictReader(open('myFile.csv', newline='')) 

totalrows = ? 

rowcount = 0 
for row in myreader: 
    rowcount +=1 
    print("Row %d/%d" % (rowcount,totalrows)) 

ben okuyucu ile yineleme tarafından toplam alabilir biliyorum, ama daha sonra 'için' döngü çalıştıramadı. Okuyucunun bir kopyasını oluşturabilirim ancak bir yineleyicinin nasıl kopyalanacağını bulamıyorum.

Ben de

totalrows = len(open('myFile.csv').readlines()) 

kullanabilirsiniz ama o dosyanın gereksiz bir yeniden açılmasını görünüyor. Mümkünse sayımı DictReader'dan almayı tercih ederim.

Herhangi bir yardım için teşekkür ederiz.

Alan

cevap

22
rows = list(myreader) 
totalrows = len(rows) 
for i, row in enumerate(rows): 
    print("Row %d/%d" % (i+1, totalrows)) 
+0

Güzel çözüm - Yineleyici fikrini oldukça yeniyim, bu yüzden şimdiye kadar enumerate() değerini gerçekten takdir etmemiştim. Saygılarımızla. –

+7

Sadece veri seti boyutunuza dikkat edin. Okuyucunuzu bir listeye dönüştürmek GOBS belleğini alabilir. –

+1

Bu, tüm verileri belleğe yükleyecek, satırları saymayacak -1 çok güzel çözümler –

2

Bir yineleyici kopyalamak nasıl bulamıyor.

Bu itertool önemli yardımcı depolama alanı gerektirebilir (:

yakın itertools.tee en dokümanlar açıklamak olarak @JFSebastian anlaşılacağı gibi, burada en iyisi, itertools.tee, ama sadece bunun bir list yapma çok geçici verilere bağlı olarak depolanması gerekir). Genel olarak, numaralı bir yineleyici, 'dan önce başka bir yineleyici kullanılmadan önce verilerin çoğunu veya tümünü kullanıyorsa, , tee() yerine list()'u kullanmak daha hızlıdır.

Sadece bir kez dosyasını açmak gerekir
+0

Her iki yöntemde de potansiyel olarak büyük kaynak tüketiminiz var. –

+0

Teşekkürler Alex - o zaman listeleyin. –

12

:

import csv 

f = open('myFile.csv', 'rb') 

countrdr = csv.DictReader(f) 
totalrows = 0 
for row in countrdr: 
    totalrows += 1 

f.seek(0) # You may not have to do this, I didn't check to see if DictReader did 

myreader = csv.DictReader(f) 
for row in myreader: 
    do_work 

olursa olsun sen iki geçiş (kayıtlarınız sabit uzunlukta ise de, yapmak zorunda ne - olası değildir - yapabildin Sadece dosya boyutunu alın ve bölün, ancak durumun böyle olmadığını varsayalım). Dosyayı tekrar açmak gerçekten çok pahalıya mal olmaz ama burada gösterildiği gibi önleyebilirsiniz. Sadece len()'u kullanmak için bir listeye dönüştürme potansiyel olarak tonlarca bellek harcayacak ve daha hızlı olmayacak.

Not: 'Pythonic' yolu += yerine enumerate kullanmaktır, fakat UNPACK_TUPLE işlemkodu yerel bir arttırılarak daha enumerate yavaşlatır ve böylece pahalı. Öyle söyleniyorsa, muhtemelen kaçınmanız gereken gereksiz bir mikro optimizasyon.

Daha Fazla Notlar: Gerçekten sadece bir çeşit ilerleme göstergesi oluşturmak istiyorsanız, mutlaka kayıt tabanlı olmak zorunda değildir. Döngüdeki dosya nesnesinde tell() kodunu kullanabilir ve yalnızca geçirdiğiniz verilerin% 'sini rapor edebilirsiniz. Biraz dengesiz olacak, ancak bir ilerleme çubuğunu garantilemek için yeterince büyük olan herhangi bir dosyadaki şanslar, kayıt uzunluğundaki sapmanın gürültüde kaybolacaktır.

+0

Nick - Cevabınız için teşekkürler. Görünüşe göre, dosyayı yeniden açmayı engellemek, fazladan kodlara değmez (okunabilirlik bu durumda performansın üzerine çıkar). Enumerate() hızı ile ilgili ipucu için teşekkürler. Tell() benim için de yeni - Daha fazla bakacağım. Saygılarımızla. –

+0

Sadece bununla ilgili problem .. eğer buhar kullanıyorsanız. – Nick

+0

@Nick: Dünyada sihir yok - bu sorun değil, sadece bir gerçek. –