> Date: Fri, 22 Jan 2016 11:00:00 +1100 > From: st...@pearwood.info > To: tutor@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@python.org > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor