2016-05-24 9 views
0

Das folgende Python-Code betrachtenPython Verwendung Speicherplatz statt RAM um nicht ausreichend RAM

with open(sys.argv[2], 'r') as fin, \ 
      open(sys.argv[3], 'w') as fout: 
     reader = csv.DictReader(fin, delimiter='%s' % sys.argv[4]) 
     writer = csv.DictWriter(fout, reader.fieldnames, dialect='excel') 
     writer.writeheader() 
     writer.writerows(reader) 

annehmen können wir eine große Datei über 2 GB haben als Eingabe und unser System hat nur 512 MB RAM, kann dies zu einem Fehler führen Memory Usage

Gibt es eine Möglichkeit, meinen Code Speicherplatz anstelle von RAM verwenden zu lassen, selbst wenn das langsam wird? oder dies ist ein Betriebssystemproblem und sollte mehr Swap zum Beispiel hinzufügen?

Update

der obige Code ist nur ein Beispiel

diesem exmaple

with io.open(sys.argv[2], 'r', encoding='utf8', errors='ignore') as fin, \ 
    io.open(sys.argv[3], 'w', encoding='utf8', errors='ignore') as fout: 
    rows = csv.DictReader(fin, delimiter='%s' % sys.argv[4]) 
    fout.write(json.dumps(list(rows), indent=4)) 
betrachten

wenn json.dumps verwenden Sie immer die Daten auf einmal schreiben müssen, und wenn Sie die angehängt werden soll Datei, müssen Sie die Datei lesen und die Daten anhängen und in die Datei schreiben, so etwas wie

data = readjson(jsonfile) 
data.append(newentry) 
jsonfile.write(json.dumps(data)) 

Update 2 Generator (faul Evolution)

ich auf diese Idee kommen, aber ich bin nicht sicher, ob es einen Unterschied

def gen(list): 
    for e in list: 
     yield e 

with open(sys.argv[2], 'r') as fin, \ 
      open(sys.argv[3], 'w') as fout: 
     reader = csv.DictReader(fin, delimiter='%s' % sys.argv[4]) 
     writer = csv.DictWriter(fout, reader.fieldnames, dialect='excel') 
     writer.writeheader() 
     writer.writerows(gen(reader)) 

with open(sys.argv[2], 'r') as fin, \ 
    open(sys.argv[3], 'w') as fout: 
    rows = csv.DictReader(fin, delimiter='%s' % sys.argv[4]) 
    # fout.write(json.dumps(gen(rows), indent=4)) -> cause error <generator object gen at 0x025BDDA0> is not JSON serializable 
    fout.write(json.dumps(gen(list(rows)), indent=4)) 
+1

Jesus, wie alt ist dieser Computer? – Carcigenicate

+0

Und wenn Sie nicht eine Struktur in den Speicher gleichzeitig lesen möchten, verwenden Sie die Faulheit der Sprache. Sie müssen nachsehen, ob Python eine Lazy-Verarbeitung unterstützt (wahrscheinlich über einen Stream). – Carcigenicate

+1

Verwenden Sie einfach eine Schleife: 'für Zeile im Leser: writer.writerow (row)'. – eryksun

Antwort

1

macht, wenn json.dumps verwenden Sie immer schreiben müssen Daten auf einmal

Nicht wirklich. Sie sollten wirklich einen Streaming-Ansatz für große Daten verwenden. In diesem Fall, so etwas wie:

fout.write('[') 
for ii, row in enumerate(rows): 
    if ii != 0: 
     fout.write(',\n') 
    json.dump(row, fout, indent=4) 
fout.write(']') 

Auf diese Weise können Sie eine Zeile zu einem Zeitpunkt, schreiben, und Sie sparen auch den Aufwand der Umsetzung all rows in ein list, die Sie nicht brauchen.

+1

Verwenden Sie ['json.dump'] (https://docs.python.org/2/library/json.html#json.dump) anstelle von' json.dumps'. – eryksun

+0

@eryksun: Gute Idee, ich habe das geändert. –