2016-04-10 18 views
5

Ich habe 2 Möglichkeiten von Zählen der Zeilen einer Datei, wie sie unten zu sehen sind. (Hinweis: Ich muss die Datei als Ganzes und nicht Zeile für Zeile lesen)Bevorzugte Art zum Zählen von Zeilen, Zeichen und Wörtern aus einer Datei als Ganzes in Python

Der Versuch, ein Gefühl dafür zu bekommen, welcher Ansatz in Bezug auf Effizienz und/oder guten Codierungsstil besser ist.

names = {} 
for each_file in glob.glob('*.cpp'): 
    with open(each_file) as f: 
     names[each_file] = sum(1 for line in f if line.strip()) 

(als here gesehen)

data = open('test.cpp', 'r').read() 
print(len(data.splitlines()), len(data.split()), len(data)) 

(als here gesehen) Und in demselben Thema in Bezug auf die die Anzahl der Zeichen Zählen und die Zählen Anzahl der Wörter in einer Datei; Gibt es einen besseren Weg als den oben vorgeschlagenen?

+1

der effizienteste Weg ist wahrscheinlich dieser, aber Sie sagen, Sie können die Datei Zeile für Zeile nicht lesen: http://stackoverflow.com/questions/14416522/counting-characters-and-lines-from-a-file- Python-2-7? lq = 1 –

+0

Ich weiß nicht über Python, aber 'wc -l' war immer gut genug für mich an einem Bash-Terminal :) –

Antwort

6

Verwenden Sie einen Generatorausdruck für die Speichereffizienz (dieser Ansatz vermeidet das Lesen der gesamten Datei in den Speicher). Hier ist eine Demonstration.

def count(filename, what): 
    strategy = {'lines': lambda x: bool(x.strip()), 
       'words': lambda x: len(x.split()), 
       'chars': len 
    } 

    strat = strategy[what] 
    with open(filename) as f: 
     return sum(strat(line) for line in f) 

input.txt:

this is 
a test file 
i just typed 

output:

>>> count('input.txt', 'lines') 
3 
>>> count('input.txt', 'words') 
8 
>>> count('input.txt', 'chars') 
33 

Man beachte, dass, wenn Zeichen zu zählen, werden die Zeilenumbrüche und gezählt. Beachten Sie auch, dass hier eine ziemlich grobe Definition von "Wort" verwendet wird (Sie haben keine angegeben), es teilt nur eine Zeile mit Leerzeichen auf und zählt die Elemente der zurückgegebenen Liste.

+0

Das ist großartig! Ich fürchte, ich verstehe nicht, wie diese Lamda-Aussagen funktionieren. Wenn du einen Link hast, der es einem Python-Neuling erklärt, wäre das ein guter Grund, einfach zu googeln, es hat keine "einfachen" Beispiele gefunden. – Karim

+1

@Karim Die Idee ist, die Python-Version des Strategie-Patterns anzuwenden. Wir ordnen Strings Funktionen (der Strategie) in einem Wörterbuch zu und wählen eine Strategie basierend auf dem zweiten Argument, das der Funktion zur Verfügung gestellt wird.Die Werte des Wörterbuchs sind reguläre Funktionen. Sie hätten diese ohne die Lambdas definieren können. Zum Beispiel entspricht der zweite Befehl 'def wordcount (line): return len (line.split())'. Wenn Sie mehr über das Lambda erfahren möchten, sind die ersten Google Hits ziemlich anständig. – timgeb

+1

@Karim auch, der erste verwendet den "Trick", den Sie nur hinzufügen können "True" und "False", zum Beispiel "True + False + True == 2". 'bool (string)' gibt 'True' für jede Zeichenfolge zurück, die nicht leer ist. – timgeb

4

Erstellen Sie einige Testdateien und testen Sie sie in einer großen Schleife, um die durchschnittlichen Zeiten zu sehen. Stellen Sie sicher, dass die Testdateien Ihren Szenarien entsprechen.

habe ich diesen Code:

import glob 
import time 

times1 = [] 
for i in range(0,1000): 
    names = {} 
    t0 = time.clock() 
    with open("lines.txt") as f: 
     names["lines.txt"] = sum(1 for line in f if line.strip()) 
     print names 
    times1.append(time.clock()-t0) 

times2 = [] 
for i in range(0,1000): 
    names = {} 
    t0 = time.clock() 
    data = open("lines.txt", 'r').read() 
    print("lines.txt",len(data.splitlines()), len(data.split()), len(data)) 

    times2.append(time.clock()-t0) 


print sum(times1)/len(times1) 
print sum(times2)/len(times2) 

und kam mit den durchschnittlichen Timings aus: ,0104755582104 und ,0180650466201 Sekunden

Dieser mit 23.000 Zeilen auf einer Textdatei war. Z. B:

print("lines.txt",len(data.splitlines()), len(data.split()), len(data)) 

Ausgänge: ('lines.txt', 23056, 161392, 1095160)

Testen Sie diese auf Ihrer aktuelle Datei! Genauere Timing-Daten zu erhalten.

Verwandte Themen