2012-12-05 11 views
31

Ho un programma che scrive una lista in un file. La lista è una lista di linee di tubazioni delimitato e le linee devono essere scritte nel file in questo modo:writelines scrive righe senza ritorno a capo, solo riempie il file ..

123|GSV|Weather_Mean|hello|joe|43.45 
122|GEV|temp_Mean|hello|joe|23.45 
124|GSI|Weather_Mean|hello|Mike|47.45 

MA scritto li fiancheggiano questo ahhhh:

123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45 

Questo programma ha scritto tutte le linee in come una linea senza interruzioni di linea .. questo mi fa molto male e io devo figura-out come invertire questo, ma in ogni caso, in cui è il mio programma male qui? Ho pensato che le linee di scrittura dovrebbero scrivere le linee verso il basso il file piuttosto che scrivere tutto a una linea ..

fr = open(sys.argv[1], 'r') # source file 
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # Target Directory Location 

for line in fr: 
    line = line.strip() 
    if line == "": 
     continue 
    columns = line.strip().split('|') 
    if columns[0].find("@") > 1: 
     looking_for = columns[0] # this is what we need to search 
    else: 
     looking_for = "[email protected]" 
    if looking_for in d: 
     # by default, iterating over a dictionary will return keys 
      new_line = d[looking_for]+'|'+'|'.join(columns[1:]) 
      line_list.append(new_line) 
    else: 
     new_idx = str(len(d)+1) 
     d[looking_for] = new_idx 
     kv = open(sys.argv[3], 'a') 
     kv.write(looking_for+" "+new_idx+'\n') 
     kv.close() 
     new_line = d[looking_for]+'|'+'|'.join(columns[1:]) 
     line_list.append(new_line) 
fw.writelines(line_list) 
+0

Sembra che tu non stia aggiungendo '" \ n "' ovunque nel tuo 'line_list'. –

+2

Puoi dare un'occhiata a [csv] (http://docs.python.org/2/library/csv.html) – esauro

+0

Dove posso aggiungere "\ n"? Lo aggiungo alla lista dell'oggetto ?? – user836087

risposta

28

Questo è in realtà un problema piuttosto comune per i principianti di Python, soprattutto perché, attraverso la libreria standard e le librerie di terze parti popolari, alcune funzioni di lettura eliminano le nuove righe, ma quasi nessuna funzione di scrittura (eccetto le cose correlate a log) aggiungili.

Quindi, c'è un sacco di codice Python là fuori che fa cose del genere:

fw.write('\n'.join(line_list) + '\n') 

o

fw.write(line + '\n' for line in line_list) 

O si è corretto, e, naturalmente, si potrebbe anche scrivere la propria funzione writelinesWithNewlines che avvolge in su ...

Ma si dovrebbe fare solo se non è possibile evitarlo.

E 'meglio se è possibile creare/mantenere i ritorni a capo in primo luogo, come nel suggerimenti di Greg Hewgill:

line_list.append(new_line + "\n") 

Ed è ancora meglio se si può lavorare a un livello superiore rispetto alle linee prime di testo, ad esempio, utilizzando il modulo csv nella libreria standard, come suggerisce esuaro.

Ad esempio, subito dopo la definizione fw, si potrebbe fare questo:

cw = csv.writer(fw, delimiter='|') 

Poi, invece di questo:

new_line = d[looking_for]+'|'+'|'.join(columns[1:]) 
line_list.append(new_line) 

A tale scopo:

row_list.append(d[looking_for] + columns[1:]) 

E a Alla fine, invece di questo:

fw.writelines(line_list) 

A tale scopo:

cw.writerows(row_list) 

Infine, il disegno è "aprire un file, quindi costruire un elenco di linee da aggiungere al file, quindi scrivere tutti in una volta". Se hai intenzione di aprire il file in alto, perché non scrivere le righe una per una? Sia che tu stia utilizzando semplici scritture o un csv.writer, ti semplificheranno la vita e il tuo codice sarà più facile da leggere. (A volte ci possono essere motivi di semplicità, efficienza o correttezza per scrivere un file tutto in una volta, ma una volta che hai spostato il open fino all'estremità opposta del programma dallo write, hai praticamente perso tutti i benefici . di tutto-at-once)

26

I documentation for writelines() stati:

writelines() non aggiunge separatori di linea

Così dovrai aggiungerli tu stesso. Per esempio:

line_list.append(new_line + "\n") 

ogni volta che si aggiunge un nuovo elemento alla line_list.

+0

+1. Questa è la soluzione più semplice, e quasi sicuramente la più appropriata se l'OP non vuole passare a qualcosa di livello superiore come 'csv'. – abarnert

+33

Che nome terribile per la funzione solo per il gusto di "accoppiare" le letture. –

-1

ho continuato finire su questo thread quando si cerca di risolvere un problema simile quando la scrittura di file in R. Quindi, per coloro che hanno avuto lo stesso problema, ecco la mia soluzione:

List_To_Be_Written_To_File<-sprintf("%s%s",as.character(List_To_Be_Written_To_File),"\n") 
6

writelines() non aggiunge separatori di riga. È possibile modificare l'elenco di stringhe utilizzando map() per aggiungere un nuovo \n (interruzione di riga) alla fine di ogni stringa.

items = ['abc', '123', '[email protected]#'] 
items = map(lambda x: x + '\n', items) 
w.writelines(items) 
1

Come altri hanno detto, e in contrasto con ciò che il nome del metodo implicherebbe, writelines non aggiunge separatori di linea. Questo è un caso da manuale per un generatore. Ecco un esempio inventato:

def item_generator(things): 
    for item in things: 
     yield item 
     yield '\n' 

def write_things_to_file(things): 
    with open('path_to_file.txt', 'wb') as f: 
     f.writelines(item_generator(things)) 

Vantaggi: aggiunge a capo esplicitamente senza modificare i valori di ingresso o di uscita o di fare qualsiasi concatenazione di stringhe disordinato. E, in modo critico, non crea nuove strutture dati in memoria. IO (scrivere su un file) è quando quel genere di cose tende a essere realmente importante. Spero che questo aiuti qualcuno!

Problemi correlati