Unfortunate exception on dict item assignment (and why aren't slices hashable?)

Bengt Richter bokr at oz.net
Mon Jul 21 07:55:01 CEST 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