slicing a bsddb table, eg. for rec in bsddb["AArdvark":"zebra"]: print rec
Bengt Richter
bokr at oz.net
Sun Jun 26 16:49:45 EDT 2005
On Sun, 12 Jun 2005 16:49:57 -0500, Skip Montanaro <skip at pobox.com> wrote:
>
> Neville> # I was expecting a slice of an index file to yield a
> Neville> # generator so not all the records need to be read from disk....
>
>Slicing is a feature of sequence types, not mapping types.
>
> >>> import string
> >>> d = dict(zip(string.lowercase, string.uppercase))
> >>> d
> {'a': 'A', 'c': 'C', 'b': 'B', 'e': 'E', 'd': 'D', ...}
> >>> d["a":"z"]
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unhashable type
> >>> import UserDict
> >>> d2 = UserDict.UserDict(d)
> >>> d2
> {'a': 'A', 'c': 'C', 'b': 'B', 'e': 'E', 'd': 'D', ...}
> >>> d2["a":"z"]
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "/Users/skip/local/lib/python2.5/UserDict.py", line 17, in __getitem__
> def __getitem__(self, key): return self.data[key]
> TypeError: unhashable type
>
>The unhashable type it's referring to is the slice object generated by the
>"a":"z" notation:
>
> >>> hash(slice("a", "z"))
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: unhashable type
>
>If you look at help on the slice type, you'll see that it takes three args:
>
> class slice(object)
> | slice([start,] stop[, step])
> |
> | Create a slice object. This is used for extended slicing
> | (e.g. a[0:10:2]).
> |
>
>Step sizes really only make sense for sequence indices.
>
Yes, but if you have an implicit sort assumption for your keys, you can treat them
as a sequence, and slice out the keys of interest and get their values, e.g.,
(no guarantees, not tested beyond what you see, that I just hacked here ;-)
>>> class SliceDict(dict):
... def __getitem__(self, i):
... if type(i) is slice:
... keys = sorted(self.keys())
... start = i.start; stop = i.stop
... try: start = keys.index(start)
... except ValueError:
... if start is not None: raise KeyError, start
... try: stop = keys.index(stop )
... except ValueError:
... if stop is not None: raise KeyError, stop
... return [dict.__getitem__(self, k) for k in keys[start:stop]]
... else:
... return dict.__getitem__(self, i)
...
>>> sd = SliceDict(a=1,b=2,z=26,k=11)
>>> sd['b':'z']
[2, 11]
>>> sd['b':]
[2, 11, 26]
>>> sd[:'z']
[1, 2, 11]
>>> sd['b':'z']
[2, 11]
>>> sd['b']
2
>>> sorted(sd.items())
[('a', 1), ('b', 2), ('k', 11), ('z', 26)]
>>> sd['x':'k']
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 8, in __getitem__
KeyError: 'x'
>>> sd['x']
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 14, in __getitem__
KeyError: 'x'
Hm, None as an actual key might be a little problematical though ;-)
I would think this could be a handy way to get data base records that were selected
from a range of sorted keys using sql and loading a dict like the above.
Regards,
Bengt Richter
More information about the Python-list
mailing list