2 Stimmen

Wie speichert man ein Wörterbuch mit utf-8-Zeichen als Schlüssel in einer Datei mit cPickle Python?

Ich möchte wissen, wie man ein Wörterbuch mit utf-8-Zeichen als seine Schlüssel in eine Datei in Python mit speichern cPickle ? dieses Wörterbuch ist sehr umfangreich und ich habe gehört, dass cPickle ist viel schneller als pickle . Ich nehme auch an, dass utf-8 kodierte Schlüssel ebenfalls problematisch sind. Jede andere schnelle Lösung ist ebenfalls willkommen. Hier ist, was ich tue und unten ist die Fehlermeldung:

unique_ngrams_dict = defaultdict(lambda: 0)# just to show how I defined my dict

dict_file = codecs.open('ngram_dict', 'w', 'utf-8')
cPickle.dump(unique_ngrams_dict,dict_file)
dict_file.close()

Fehlermeldung:

Traceback (most recent call last):
  File "Generate_NGram.py", line 81, in <module>
    save_ngram_dict(unique_ngrams_dict)
  File "Generate_NGram.py", line 70, in save_ngram_dict
    cPickle.dump(unique_ngrams_dict,dict_file)
  File "/usr/lib/python2.6/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle function objects

danke

2voto

Jan Hudec Punkte 69126
  1. Pickle ist ein binär Format, also sollten Sie die Datei nicht mit irgendwelchen Codecs öffnen, sondern nur:

    file('ngram_dict', 'w')

    Das ist kein Grund für das Scheitern, sondern nur ziemlich ineffizient.

  2. Das eigentliche Problem ist, dass das Objekt, das Sie zu speichern versuchen, einen Funktionsverweis enthält (der Standardwert lambda: 0 ) und das Pickle-Format unterstützt keine Serialisierungsfunktionen.

    Sie haben drei Möglichkeiten:

    1. Verwenden Sie ein normales dict und verwenden Sie seine .get Methode mit Standardargument.

    2. Satz

      unique_ngrams_dict.default_factory = None

      vor dem Beizen und stellen Sie es zurück auf

      unique_ngrams_dict.default_factory = lambda: 0

      nach dem Entpickeln.

    3. Definieren Sie eine Klasse wie:

      class NgramDefault:
          def __call__():
              return 0

      und verwenden NgramDefault() als Standardwerk anstelle von lambda: 0 .

0voto

Omnifarious Punkte 52299

Sie sollten es einfach tun und darauf vertrauen, dass das Beizmodul das Richtige tut. Am besten behandeln Sie Pickle als einen undurchsichtigen Klumpen, der auf magische Weise genau die Datenstruktur wiederherstellt, mit der Sie begonnen haben, wenn Sie ihn entpickeln.

Versuchen Sie nicht, irgendeine Art von Kodierung auf die Ausgabe von pickle anzuwenden, sie sollte wie ein binärer Blob behandelt werden. Wenn Sie Unicode-Elemente haben, wenn Sie pickle, werden sie Unicode sein, wenn Sie unpickle.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X