Seite 1 von 1

Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 15:51
von martinjo
Hallo

Ich komme bei einem Skript nicht weiter.

Code: Alles auswählen

import sys, csv
...
csv_reader_shipments_all = csv.DictReader(input_file)
for line in csv_reader_shipments_all:
    print line
Soweit ist alles ok, jetzt möchte ich aber zuvor noch die Länge von csv_reader_shipments_all ausgeben.

Nutze ich dazu len(list(csv_reader_shipments_all)) führt das dazu, dass csv_reader_shipments_all durchlaufen wird und "for line in" nicht mehr funktioniert.

Mein erster Lösungsversuch habe ich ergoogelt und den Hinweis gefunden, mit seek den CSV_Reader zurückzusetzen:
AttributeError: DictReader instance has no attribute 'seek'

Beim zweiten Versuche wollte ich eine Kopie der Instanz anlegen, was aber anscheinend nichts bringt, da auf das selbe Objekt? verwiesen wird. Das bedeutet ist die Kopie durchgelaufen ist auch das Original durchgelaufen?
Das sind aber auch nur Vermutungen.

Hier noch der Namensraum meines DictReader welcher kein seek besitzt:

Code: Alles auswählen

['__doc__', '__init__', '__iter__', '__module__', '_fieldnames', 'dialect', 'fieldnames', 'line_num', 'next', 'reader', 'restkey', 'restval']
Meine Fragen nun, warum habe ich kein seek und wie mache ich das sonst am besten wenn ich nicht in der Schleife erst zählen will?

Danke

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 15:56
von cofi
``DictReader`` arbeitet auf einer Datei und den Pointer dieser Datei willst du zuruecksetzen:

Code: Alles auswählen

In [1]: import csv

In [2]: f = open('tmp/test.csv')

In [3]: for line in csv.DictReader(f):
   ...:     print line
   ...:     
{'baz': '3', 'foo': '1', 'bar': '2'}
{'baz': '6', 'foo': '4', 'bar': '5'}

In [4]: f.seek(0)

In [5]: for line in csv.DictReader(f):
    print line
   ...:     
{'baz': '3', 'foo': '1', 'bar': '2'}
{'baz': '6', 'foo': '4', 'bar': '5'}
Was deine Kopie-Vermutungen angeht: Das kommt darauf an, wie du deine Kopie erstellst. In dem Fall hier ist die Ursache aber, dass der Zustand in dem Datei-Objekt steckt und nicht im Reader.

Zu guter letzt: Was willst du denn eigentlich machen?

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 16:07
von martinjo
Danke

Das mit dem neu setzen des Pointers wollte ich vermeiden, da dies in einer anderen Funktion geschieht:

Code: Alles auswählen

# read all shipments
def read_csv_input_file(csv_file):
    input_file = codecs.open(csv_file, "rb")
    csv_reader = csv.DictReader(input_file, delimiter=';')
    return csv_reader

Code: Alles auswählen

def seperate_shipments(csv_reader_shipments_all):0
    #csv_reader_shipments_all_len = len(list(copy.copy(csv_reader_shipments_all_copy)))
    shipments_all_1 = []
    shipments_all_2 = []
    for line in csv_reader_shipments_all:
            if line["Pickup Company"] == "company1":
                shipments_all_1.append(line)
            else:
                shipments_all_2.append(line)
    print "shipments 1 =\t %s" % len(shipments_all_1)
    print "shipments 2 =\t %s" % len(shipments_all_2)

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 16:16
von martinjo
also ich habe die input_file in der ersten Funktion nun global definiert, so kann ich die Datei auch in der zweiten Funktion zurücksetzen, nicht schön aber ich bin ja noch Anfänger und darf das^^

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 16:18
von cofi
Eine Alternative waere auf einer Liste des DictReader-Iterators zu arbeiten, statt auf dem Iterator selbst. Das hat aber zur folge, dass du die Datei komplett einliest und CSV-Dateien haben ja die Neigung zu wachsen ...

Eine weitere waere das Nachzaehlen von ``enumerate`` erledigen zu lassen.

Es ist zwar schoen, dass du deinen Code in kleine Funktionen zerlegst, aber `read_csv_input_file` tut reichlich wenig und schlimmer noch: Sie verbaut dir jeglichen sinnvollen Umgang mit der Datei, inklusive sie zu schliessen, wenn du fertig bist.

Aber wenn du nicht damit herausruecken willst, was du eigentlich vorhast ...

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 16:27
von martinjo
He, ich dachte was ich damit Vorhabe ist mit dem Code welchen ich als letztes gepostet habe ersichtlich, ich will einfach nur 2 Listen erstellen damit ich die Anzahl der Shipments pro Company habe :D und damit habe ich dann halt noch ein wenige experimentiert.

Bisher hatte ich immer das Problem, dass ich zu wenig Funktionen erstellt habe und später viel zu oft doppelten Code drin hatte, bei diesem Skript mal wollte ich das mal von Anfang an richtig machen.

Aber ich glaube ich komme nun zurecht, der Hinweis, dass es eben die Datei und nicht die CSV_Reader Instanz ist hat mir geholfen, Danke nochmal!

Re: Länge von DictReader Instanz

Verfasst: Dienstag 11. Dezember 2012, 17:42
von cofi
Naja das zeigt was du machst, aber nicht was dein Ziel ist.

Wenn ich dich frage wohin du laeufst, ist die passende Antwort ja auch nicht "bis zur naechsten Kurve", wenn du eigentlich in die naechste Stadt willst ;)