2016-05-13 20 views
0

Ich versuche, eine Funktion zu erstellen, die dynamisch löscht und Aufträge Zeilen basierend auf den Spaltennummern in geben Bisher habe ich definiert die folgenden:.Dynamische Argumente in Python schreiben

import csv 

def delete(rows_to_keep): 
    with open('file.csv','r') as source: 
     rdr= csv.reader(source) 
     with open('reordered.csv','w') as result: 
      wtr= csv.writer(result, delimiter=',', lineterminator='\n') 
      for r in rdr: 
       wtr.writerow(...) 

rows_to_keep = [1, 3, 5, 6] 

delete(rows_to_keep) 

jedoch in der oben, möchte ich die ... in der writerow (...) durch Argumente ersetzt werden, wie folgt:

... = r[1], r[3], r[5], r[6] 

dh

wtr.writerow(r[1], r[3], r[5], r[6]) 

Und haben die Anzahl der Argumente und Reihenfolge je nachdem, was übergeben wird.

Ich bin nicht ganz sicher, wie ich das tun könnte, wenn plötzlich das Array 10 Werte hat. Irgendwelche Ideen??

Antwort

2

Verwenden Sie rows_to_keep in einer Schleife, um eine Liste mit der neuen Sequenz von Werten zu erstellen, die Sie ausschreiben möchten. Übergeben Sie diese Liste dann an writerow(); Es akzeptiert keine willkürliche Anzahl von Argumenten, daher müssen Sie es auf die eine oder andere Weise mit einer Liste aufrufen. Etwas wie dieses:

rows_to_keep = [1, 3, 5, 6] 
... 
for row in rdr: 
    newrow = list() 
    for n in rows_to_keep: 
     newrow.append(row[n]) 
    wtr.writerow(newrow) 

PS. Oder verwenden Sie ein Verständnis, wenn Sie bevorzugen. Gleiches Ergebnis (bei korrekter Verwendung).

for row in rdr: 
    newrow = [row[n] for n in rows_to_keep] 
    wrt.writerow(newrow) 
+0

Funktioniert perfekt danke! – NickP

+0

Ich würde immer ein Listenverständnis verwenden: dafür sind sie da. Im ersten Beispiel würde "list()" üblicherweise einfach als "[]" geschrieben. – EOL

+0

Die Verständlichkeit ist großartig, aber für neue Programmierer sind sie schwer zu verstehen. Da es nicht die Frage ist, über die ich mich ausspreche, entschied ich mich dafür, es einfach und explizit zu halten. YMMV. – alexis

2

Sie können eine Liste Verständnis verwenden:

wtr.writerow([r[col] for col in rows_to_keep]) 
+0

Wenn ich die Frage richtig verstehe, ist 'writerow (* [r [col] für col in rows_to_keep]) 'tatsächlich angebracht, um den gleichen Effekt wie'' wtr.writerow (r [1], r [3 ], r [5], r [6]) '". – EOL

+0

Nicht ganz, @EOL: 'writerow()' mit mehreren Argumenten ist ein Syntaxfehler. Aber ja, das sollte "r [col]" im Verständnis sein. – alexis

+0

Entschuldigung, aktualisiert. –

1

Vielleicht haben Sie columns_to_keep gemeint und übergeben Sie die Liste der Spalten als eine Liste an die Funktion zu halten. Sie können operator.itemgetter hier verwenden

import csv 
import operator 

def prune_columns(columns_to_keep): 
    with open('file.csv', 'r') as source,\ 
     open('reordered.csv','w') as result: 
     rdr = csv.reader(source) 
     wtr = csv.writer(result, delimiter=',', lineterminator='\n') 

     select = operator.itemgetter(*columns_to_keep) 
     # select is now a function that returns a tuple that 
     # returns elements 1, 3, 5 and 6 of the input 

     for row in rdr: 
      wtr.writerow(select(row)) 

prune_columns(columns_to_keep=[1, 3, 5, 6])