2013-09-25 14 views

risposta

39

È possibile utilizzare sum() con un generatore di espressione:

with open('data.txt') as f: 
    print sum(1 for _ in f) 

Si noti che non è possibile utilizzare len(f), dal momento che è un fiterator. _ è un nome di variabile speciale per le variabili throwaway, vedere What is the purpose of the single underscore "_" variable in Python?.

È possibile utilizzare len(f.readlines()), ma questo creerà un ulteriore elenco in memoria, che non funzionerà nemmeno su file enormi che non si adattano alla memoria.

+1

Così pithonic, quindi molto pythonic: O – SARose

+0

Sarebbe più rapido se lo scriveste come con open ('data.txt') come f: print sum ([1 per _ in f])? – jimh

+0

@jimh - è meglio usare solo 'sum (1 per _ in f)' perché usa implicitamente un'espressione di generatore tra parentesi e non crea un elenco di 1s. Tuttavia, la tua versione 'sum ([1 for _ in f])' creerebbe una lista di 1 prima di sommarli, il che alloca inutilmente la memoria. – blokeley

4
count=0 
with open ('filename.txt','rb') as f: 
    for line in f: 
     count+=1 

print count 
8

È possibile utilizzare sum() con un'espressione generatore qui. L'espressione del generatore sarà [1, 1, ...] fino alla lunghezza del file. Quindi chiamiamo sum() per aggiungerli tutti insieme, per ottenere il conteggio totale.

with open('text.txt') as myfile: 
    count = sum(1 for line in myfile) 

Sembra da ciò che hai provato che non vuoi includere righe vuote. È quindi possibile fare:

with open('text.txt') as myfile: 
    count = sum(1 for line in myfile if line.rstrip('\n')) 
17

Questo link (How to get line count cheaply in Python?) ha un sacco di possibili soluzioni, ma tutti ignorano un modo per rendere questo percorso notevolmente più veloce, vale a dire utilizzando l'interfaccia unbuffered (grezzo), utilizzando bytearrays, e facendo il tuo buffering.

utilizzando una versione modificata dello strumento tempi, credo che il seguente codice è più veloce (e marginalmente più divinatorio) rispetto a qualsiasi delle soluzioni offerte:

def _make_gen(reader): 
    b = reader(1024 * 1024) 
    while b: 
     yield b 
     b = reader(1024*1024) 

def rawpycount(filename): 
    f = open(filename, 'rb') 
    f_gen = _make_gen(f.raw.read) 
    return sum(buf.count(b'\n') for buf in f_gen) 

qui sono i miei tempi:

rawpycount  0.0048 0.0046 1.00 
bufcount   0.0074 0.0066 1.43 
wccount    0.01 0.01 2.17 
itercount   0.014 0.014 3.04 
opcount   0.021 0.02 4.43 
kylecount   0.023 0.021 4.58 
simplecount  0.022 0.022 4.81 
mapcount   0.038 0.032 6.82 

vorrei postare lì, ma io sono un relativamente nuovo utente di impilare scambio e non hanno la manna necessaria.

EDIT:

Questo può essere fatto completamente con i generatori di espressioni in-line utilizzando itertools, ma diventa piuttosto strano cercando:

+2

Grazie! Questa implementazione di itertool è velocissima e mi consente di dare una percentuale di completamento quando viene letto un file molto grande. –

+0

Ricevo un errore: AttributeError: l'oggetto 'file' non ha attributo 'raw'. Qualche idea, perché? – MD004

+0

Il codice qui è specifico per python 3 e la divisione raw/unicode è avvenuta lì. La mia memoria di Python 2 non è buona a questo punto, ma se stai usando python 2, penso che se cambi la modalità sulla chiamata open() a 'r' e cambi semplicemente "f.raw.read()" in "f.read()" otterrai effettivamente la stessa cosa in python 2. –

0

questo si dà anche le linee Numero locali in un file .

a=open('filename.txt','r') 
l=a.read() 
count=l.splitlines() 
print(len(count)) 
2

uno di linea:

total_line_count = sum(1 for line in open("filename.txt")) 

print(total_line_count) 
0

Usa:

num_lines = sum(1 for line in open('data.txt')) 
print(num_lines) 

che funzionerà.

0

Per le persone che dicono di usare with open ("filename.txt","r") as f si può fare anyname = open("filename.txt","r")

def main(): 

    file = open("infile.txt",'r') 
    count = 0 
    for line in file: 
      count+=1 

    print (count) 

main() 
0

ecco come si può fare attraverso la lista di comprensione, ma questo sarà sprecare un po 'di memoria del computer come line.strip() è stato chiamato due volte.

 with open('textfile.txt') as file: 
lines =[ 
      line.strip() 
      for line in file 
      if line.strip() != ''] 
print("number of lines = {}".format(len(lines))) 
Problemi correlati