Unfortunate exception on dict item assignment (and why aren't slices hashable?)
Bengt Richter
bokr at oz.net
Mon Jul 21 01:55:01 EDT 2003
On Sun, 20 Jul 2003 21:04:29 -0700, Erik Max Francis <max at alcyone.com> wrote:
>Jeff Epler wrote:
>
>> I'd have expected something like 'TypeError: unslicable type'
>> meaning that you can't slice a dict, not that slice()s aren't
>> hashable.
>
>Slicing is not a feature of the mapping interface; it's not entirely
>clear what it should mean. All mapping interfaces need are keys that
>are hashable; it doesn't make any kind of requirements about how those
>keys related to each other. So slicing a mapping interface is something
>that simply may not make any sense at all in some cases.
>
>If you really _do_ want to take a range out of a dictionary and know
>that it has some meaning, you should probably do the slicing on the
>_list of keys_ (D.keys()) -- because there is no concept of an ordering
>of keys in a dictionary.
>
It might be interesting to define a dict slice
as a lexicographic slice -- e.g.,
====< slicedict.py >=========================================
class SD(dict):
from types import SliceType
def __getitem__(self, i):
if isinstance(i, self.SliceType):
keys = self.keys()
keys.sort()
try: start = keys.index(i.start)
except ValueError: start = 0
try: stop = keys.index(i.stop)
except: stop = len(keys)
step = i.step or 1
return SD([(k, dict.__getitem__(self, k))
for k in [keys[j] for j in xrange(start,stop,step)]])
return dict.__getitem__(self, i)
=============================================================
>>> import slicedict
>>> sd = slicedict.SD(zip([chr(c) for c in range(ord('a'),ord('z')+1)],range(26)))
>>> sd['c':'g']
{'c': 2, 'e': 4, 'd': 3, 'f': 5}
>>> sd['c':'g':2]
{'c': 2, 'e': 4}
>>> sd['c':'h':2]
{'c': 2, 'e': 4, 'g': 6}
>>> sd[:'c']
{'a': 0, 'b': 1}
>>> sd[:'w']
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 1
2, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'v': 21}
>>> sd['w':]
{'y': 24, 'x': 23, 'z': 25, 'w': 22}
>>> sd[:]
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8, 'h': 7, 'k': 10, 'j': 9, 'm': 1
2, 'l': 11, 'o': 14, 'n': 13, 'q': 16, 'p': 15, 's': 18, 'r': 17, 'u': 20, 't': 19, 'w': 22, 'v'
: 21, 'y': 24, 'x': 23, 'z': 25}
>>> sd[::5]
{'a': 0, 'p': 15, 'u': 20, 'f': 5, 'k': 10, 'z': 25}
Regards,
Bengt Richter
More information about the Python-list
mailing list