[Tutor] Why is an OrderedDict not sliceable?
Albert-Jan Roskam
sjeik_appie at hotmail.com
Sun Jan 24 15:15:33 EST 2016
> Date: Fri, 22 Jan 2016 11:00:00 +1100
> From: steve at pearwood.info
> To: tutor at python.org
> Subject: Re: [Tutor] Why is an OrderedDict not sliceable?
>
> Further thoughts on your question...
>
>
> On Wed, Jan 20, 2016 at 01:33:17PM +0000, Albert-Jan Roskam wrote:
> > Hi,
> >
> > Like the subject says: Why is an OrderedDict not sliceable? (From the
> > collections library). Was that an intentional omission, or a mistake?
> > [1]
> >
> > Background: I do not use OrderedDict very often, but I thought I could
> > use it to look up street and city names using postcodes ([0-9]{4}
> > [a-z]{2} format). I needed it to be ordered because I also wanted to
> > be able to use bisect, which is needed when the postcode letters are
> > missing. In short: a fast dict lookup for complete postcodes and less
> > fast bisect lookup for in complete postcodes.
>
> I'm not sure I understand your use-case here.
>
> You have postcodes that look like this:
>
> "1234az"
>
> Correct? Why do you want them *ordered*?
>
> I think you are confusing OrderedDict for a "Sorted Dict". OrderedDict
> doesn't keep the keys in sorted order, it keeps them in the order that
> they were inserted. So unless you are super-careful to insert the
> postcodes in sorted order, the order of them in the dict will be
> whatever order you insert them:
You are right. See also my reply to Mark Lawrence, who made a similar remark.
> py> from collections import OrderedDict
> py> d = OrderedDict()
> py> d['1234az'] = "1 Smith Street"
> py> d['9999zz'] = "991203 Short Street"
> py> d['3456mx'] = "24 Hour Lane"
> py> for key in d:
> ... print(key, d[key])
> ...
> 1234az 1 Smith Street
> 9999zz 991203 Short Street
> 3456mx 24 Hour Lane
>
>
> So even if OrderedDict supported slicing, that would not do what you
> think it does.
Oscar Benjamin's link about collections.OrderedDict.__eq__ (or rather, the fact that it's not reimplemented) scared the heck outta me :-)
Maybe this class should be avoided altogether?
> Also, you have a problem -- what happens if the incomplete postcode is
> missing the first digit? (I suppose for that case, you just have to do a
> slow linear search.) What about transposed digits or other errors? I'm
> glad I don't have to solve that problem!
>
>
> Anyway, I suggest doing something like this:
>
> (1) Keep the known postcodes in a regular dict, not an ordered dict.
>
> (2) Once you have built the dict, then copy the keys and sort them:
>
> postcodes = {
> '1234az': "1 Smith Street",
> '9999zz': "991203 Short Street",
> '3456mx': "24 Hour Lane",
> }
>
> array = sorted(postcodes.keys())
>
>
> (3) Each time you add a new postcode to the dict, use bisect to add it
> to the array as well. To ensure you never forget, use a helper function:
But I only *read* from the postcode table. I never insert any postcodes, nor do I delete any (ok, a few times a year I load new definitions from the database, because new houses, with new postcodes, will have been built). See also my mail to Alan (today).
> def insert(postcode, entry):
> if postcode in postcodes:
> # deal with duplicate/existing key
> ...
> else:
> postcodes[postcode] = entry
> bisect.insort(array, postcode)
>
>
> Same for deleting.
>
>
>
> --
> Steve
> _______________________________________________
> Tutor maillist - Tutor at python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
More information about the Tutor
mailing list