2016-07-12 7 views
0

Ich bin neu in Python. In einer Aufgabe muss ich lines.For Beispiel ein Zeichen, bevor spezifische hinzufügen, in meinem Text derEffizienter und allgemeiner Weg, Text vor Zeilen einer Datei voranzustellen?

Namen

und

Datei

Name

sind die Festnetzlinien, auf denen ich entweder ; basierend auf dem Flag

hinzufügen oder löschen muss 10
hey : see 
;Name:blah 
;Surname:blah 

Dies ist der Code, den ich für den gleichen geschrieben habe ... Ist es effizient genug? Können wir effizienter schreiben und können wir

Name und Vorname

als Argumente, die ich die Schlüsselwörter als ein Parameter der Funktion bedeuten, zu dem hinzufügen

passieren;

def changefile(filepath,flag): 
    # flag = 1 
    final = "" 
    with open(filepath) as content: 
     for line in content: 
      if flag==1: 
       if line.split(":")[0]==";Name" or line.split(":")[0]==";Surname": 
        final += line[1:] 
       else: 
        final += line 
      else: 
       if line.split(":")[0]=="Name" or line.split(":")[0]=="Surname": 
        final += ";" 
       final += line 
    f = open(filepath, 'r+') 
    f.truncate() 
    f.write(final) 
    f.close() 


changefile("abc.txt",0) 
+2

Wenn es funktioniert, funktioniert es .... das ist nicht [Code Review] (http://codereview.stackexchange.com/). Trotzdem kann ich mir nicht vorstellen, warum das keine gute Lösung ist. – Aaron

+1

string + = string ist ein Anti-Muster in Python; Obwohl [CPython es optimiert] (http://stackoverflow.com/a/19926932/478656), ist es nicht sehr Pythonic, und das Erstellen einer Liste und dann das Hinzufügen ist eher performant gegenüber mehr Versionen und Implementierungen von Python. Das ist das größte potenzielle "Ineffizienz", das ich sehen kann. Das heißt, [optimieren Sie nicht, es sei denn, Sie wissen, dass Sie müssen.] (Http://stackoverflow.com/a/1316959/478656). Ich wäre viel mehr besorgt über die Lesbarkeit von Dingen wie Ihrem vagen Flagnamen, Ihrem vagen Funktionsnamen, mit 1,0 anstelle von True, False. – TessellatingHeckler

Antwort

0

ich es steckte viel, und Martineaus Ideen entlehnt, und endete mit auf den Punkt:

def change_file(filepath, add_comment, trigger_words): 

    def process(line): 
     line_word = line.lstrip(';').split(':')[0] 

     if line_word in trigger_words: 
      if add_comment: 
       line = line if line.startswith(';') else ';' + line 
      else: 
       line = line.lstrip(';') 

     return line 


    with open(filepath) as f: 
     content = [process(line) for line in f] 


    with open(filepath, 'r+') as f: 
     f.truncate() 
     f.write(''.join(content)) 


change_file('abc.txt', add_comment=True, trigger_words=["sys", "netdev"]) 

Das Haupt „nett“ Bit (das Ich mag) wird eine Liste Verständnis mit [process(line) for line in f], weil es mit der ganzen final = ''; final += blah Anordnung weggeht. Es verarbeitet jede Zeile und das ist die Ausgabe.

ich die flag so anstelle des Lesens geändert haben „Flag 0 oder 1“ (was bedeutet das?) Es jetzt „add_comment wahr oder falsch ist“, klarer zu zeigen, was sie tut .

In Bezug auf Effizienz könnte es besser sein; (Machen Sie "trigger_words" zu einem Satz, so dass die Testmitgliedschaft schneller war, ändern Sie die Art und Weise, wie es jede Zeile zum Testen normalisiert); Aber wenn Sie eine kleine Datei verarbeiten, wird es keinen großen Unterschied machen. Python ist schnell genug, und wenn Sie eine riesige Datei verarbeiten, ist es wahrscheinlicher, dass IO begrenzt ist als CPU-begrenzt.

Versuchen Sie es online hier: https://repl.it/CbTo/0 (es liest und druckt die Ergebnisse, es versucht nicht zu speichern).

(NB. .lstrip(';') entfernt alle Semikolons am Anfang der Zeile, nicht nur eine. Ich nehme an, es gibt nur eine).


Edit von den Kommentaren. Hier ist eine Version, die die SQL Server UTF-16-Installationsdatei verarbeitet, ohne es zu vermasseln, aber ich kenne keinen allgemeinen Fix für diese, der für alle Dateien funktioniert. Beachten Sie, das liest die Datei als eine bestimmte Datencodierung und schreibt eine binäre Datei mit einer bestimmten Datencodierung. Und ändert die Aufteilung in = für das SQL-Ini-Format.Und nicht truncate, weil w Modus das tut.

import codecs 

def change_file(filepath, add_comment, trigger_words): 

    def process(line): 
     line_word = line.lstrip(';').split('=')[0] 

     if line_word in trigger_words: 
      if add_comment: 
       line = line if line.startswith(';') else ';' + line 
      else: 
       line = line.lstrip(';') 

     return line 


    with codecs.open(filepath, encoding='utf-16') as f: 
     content = [process(line) for line in f] 

    with codecs.open(filepath, 'wb', encoding='utf-16') as f: 
     f.write(''.join(content)) 


change_file('d:/t/ConfigurationFile - Copy.ini', add_comment=True, trigger_words=["ACTION", "ENU"]) 
+0

danke für die Lösung es funktioniert gut für die TXT-Datei wie in der Frage erwähnt ... aber wenn ich die gleiche Lösung auf die Konfigurationsdatei anwenden meine Konfigurationsdatei wird beschädigt .... können Sie mir helfen, dass – user2591307

+0

@ user2591307 vielleicht, wenn Sie erklären, was Sie mit "beschädigt" meinen, weil ich nicht erraten kann. – TessellatingHeckler

+0

http://pastebin.com/Uh27t5Q8 – user2591307

Verwandte Themen