5

I want to use a tuple (1,2,3) as a key using the shelve module in Python. I can do this with dictionaries:

d = {}
d[(1,2,3)] = 4

But if i try it with shelve:

s = shelve.open('myshelf')
s[(1,2,3)] = 4

I get: "TypeError: String or Integer object expected for key, tuple found"

Any suggestions?

4 Answers4

8

How about using the repr() of the tuple:

s[repr((1,2,3))] = 4
Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
7

As per the docs,

the values (not the keys!) in a shelf can be essentially arbitrary Python objects

My emphasis: shelf keys must be strings, period. So, you need to turn your tuple into a str; depending on what you'll have in the tuple, repr, some separator.join, pickling, marshaling, etc, may be fruitfully employed for that purpose.

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
1

Why not stick with dictionaries if you want to have arbitray keys ? The other option is to build a wrapper class around your tuple with a repr or str method to change it to a string. I am thinking of a library(natural response to shelves) - your tuple can be the elements in the Dewey decimal and the str creates a concatenated complete representation.

whatnick
  • 5,400
  • 3
  • 19
  • 35
1

This may be an old question, but I had the same problem.

I often use shelve's and frequently want to use non-string keys. I subclassed shelve-modules class into a shelf which automatically converts non-string-keys into string-keys and returns them in original form when queried. It works well for Python's standard immutable objects: int, float, string, tuple, boolean.

It can be found in: https://github.com/North-Guard/simple_shelve

NorthGuard
  • 11
  • 2