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