Anish Kumar wrote: > >> 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. > > Well no, take the case of [1,100] and [2,0] > Both belong to same bin suppose then it should > be sorted based on second index and I would > expect [2,0] [1,100] as output. > This is not happening currently with the original > code I have sent.
I think that is because you do not consider all three cases. Let's start with a function cmp() modeled after the Python 2 built-in def cmp(a, b): if a < b: return -1 elif a > b: return 1 return 0 Then your comparator could be fixed (I think) as follows def compare(x, y): def bin(a): return a[0] // 3 result = cmp(bin(x), bin(y)) if result: return result return cmp(x[1], y[1]) and that "fixed" version would be equivalent (I think) to def compare(x, y) def key(a): return (a[0] // 3, a[1]) return cmp((key(x), key(y)) That said, even if you use Python 2 you should use sorted() with a key function rather than a comparison -- as shown below. Did that work for you? >>> 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 [...] >> """ _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor