Pickling dictionaries containing dictionaries: failing, recursion-style!

John Machin sjmachin at lexicon.net
Sat Dec 1 18:11:28 EST 2007


On Dec 2, 8:59 am, lysdexia <doug.shaw... at gmail.com> wrote:
> I'm having great fun playing with Markov chains. I am making a
> dictionary of all the words in a given  string, getting a count of how
> many appearances word1 makes in the string, getting a list of all the
> word2s that follow each appearance of  word1 and a count of how many
> times word2 appears in the string as well. (I know I should probably
> be only counting how many times word2 actually follows word1, but as I
> said, I'm having great fun playing ...)
>
> printed output of the dictionary looks like so:
>
> {'and': [1, {'to': 1}], 'down': [1, {'upon': 1}], 'them': [1, {'down':
> 1}], 'no': [1, {'others': 1}], 'this': [1, {'it': 1}], 'is': [2, {'a':
> 2}], 'upon': [1, {'a': 1}], 'it': [2, {'is': 2}], 'think': [2, {'and':
> 1, 'words': 1}], 'write': [1, {'this': 1}], 'to': [3, {'write': 1,
> 'put': 1, 'think': 1}], 'words': [1, {'no': 1}], 'others': [1,
> {'think': 1}], 'put': [1, {'them': 1}], 'sin': [2, {'to': 2}]}
>
> Here's the actual function.
>
> def assembleVocab(self):
>   self.wordDB = {}
>   for word in self.words:
>     try:
>       if not word in self.wordDB.keys():
>         wordsWeights = {}
>         afterwords =  [self.words[i + 1] for i, e in
> enumerate(self.words) if e == word]
>         for aw in afterwords:
>           if not aw in wordsWeights.keys():
>             wordsWeights[aw] = afterwords.count(aw)
>         self.wordDB[word] = [self.words.count(word), wordsWeights]
>     except:
>       pass
>   out = open("mchain.pkl",'wb')
>   pickle.dump(self.wordDB, out, -1)
>   out.close()
>
> My problem is, I can't seem to get it to unpickle. When I attempt to
> load the
> saved data, I get:
>
> AttributeError: 'tuple' object has no attribute 'readline'
>
> with pickle, and
>
> TypeError: argument must have 'read' and 'readline' attributes

The code that created the dictionary is interesting, but not very
relevant. Please consider posting the code that is actually giving the
error!
>
> Looking at the pickle pages on docs.python.org, I see that I am
> indeed
> supposed to be able to pickle ``tuples, lists, sets, and dictionaries
> containing only picklable objects''.
>
> I'm sure I'm missing something obvious.  Clues?

The docs for pickle.load(file) say """
Read a string from the open file object file and interpret it as a
pickle data stream, reconstructing and returning the original object
hierarchy. This is equivalent to Unpickler(file).load().

file must have two methods, a read() method that takes an integer
argument, and a readline() method that requires no arguments. Both
methods should return a string. Thus file can be a file object opened
for reading, a StringIO object, or any other custom object that meets
this interface.
"""

The error message(s) [plural??] that you are getting suggest(s) that
the argument that you supplied was *not* an open file object nor
anything else with both a read and readline method. Open the file in
binary mode ('rb') and pass the result to pickle.load.



More information about the Python-list mailing list