[Tutor] custom comparator with ordered list

Peter Otten __peter__ at web.de
Mon Jun 26 05:35:08 EDT 2017


anish singh wrote:

> I need a custom comparator.
> 
> dictionary = {a:[b,c], d:[e,f]}
> 
> If both 'b' and 'e' belong to the same bin
> then it should be compared based on 'c' and 'f'.
> 
> However, I want to also represent the result of the
> sorted operation in a ordered dictionary as order is
> important.
> 
> My custom comparator is something like this:
> 
> 
> ''' x and y is a list of two elements each'''
> def cmpr(x, y):
>     r = 3
>     if x[0]//r != y[0]//r:
>         return x[0]//r < y[0]//r
>     return x[1] < y[1]

This looks like it should be called less() rather than compare() as it 
doesn't differentiate between the x < y and x == y case.

> Please note it is not exactly comparing the first elements
> of the value but checking if they belong to the same bin
> and they do then it checks the second element as as shown
> above.

The effect should be the same.
 
> Example:
> {0:[0, 8], 1:[2, 5], 2:[2, 11], 3:[16, 17], 4:[13, 14], 5:[1, 17], 6:[17,
> 17] }
> output should be:
> {1:[2, 5], 0:[0, 8], 2:[2, 11], 5:[1, 17], 4:[13, 14], 3:[16, 17], 6:[17,
> 17] }

>>> input = {0:[0, 8], 1:[2, 5], 2:[2, 11], 3:[16, 17], 4:[13, 14], 5:[1, 
17], 6:[17,
... 17] }
>>> wanted = {1:[2, 5], 0:[0, 8], 2:[2, 11], 5:[1, 17], 4:[13, 14], 3:[16, 
17], 6:[17,
... 17] }
>>> output = {k: v for k, v in sorted(input.items(), key=lambda x: (x[1]
[0]//3, x[1][1]))}
>>> assert list(output.items()) == list(wanted.items())

As written it will work with CPython 3.6. However, for compatibility with 
other versions of Python I recommend that you replace the plain dicts above 
with collections.OrderedDict instances. Quoting

https://docs.python.org/dev/whatsnew/3.6.html#whatsnew36-pep520

"""
The order-preserving aspect of this new [dict] implementation is considered 
an implementation detail and should not be relied upon [...]
"""



More information about the Tutor mailing list