New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove cmp parameter to list.sort() and builtin.sorted() #46104
Comments
We should either change the API so you can pass in a '<' comparator, or |
I support removal; however, there is an uncommon corner-case that is |
Forgot to mention, the easy work-around is to do two consecutive sorts l.sort(key=secondary, reverse=True)
l.sort(key=primary) |
Let's do this. It is a nice simplification and makes the sort tools |
Patch attached for the C files making them much cleaner and a bit |
Cool! Doesn't it feel good to rip out stuff? :-) I do hope that you'll make sure all tests pass (-uall) before submitting |
Yes, it does feel great. The code is cleaner and faster. The API is After more thought, I would like to make one more change and require the The issue is that the cmp= interface has been around so long that it is For the 2-to-3 tool, I wrote a converter that automatically transitions 2.6 code: s.sort(cmp=lambda p, q: cmp(p.lower(), q.lower())) Ideally, the automatcic conversion would be accompanied by a suggestion 3.0 code: s.sort(key=str.lower) --- converter code --- def CmpToKey(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __cmp__(self, other):
return mycmp(self.obj, other.obj)
return K |
Works for me. (To be honest I thought key was already required to be a |
Checked-in rev 60453. |
Is this really necessary? I see that the sorting code gets a little simpler, but I believe that For instance, if you have an algorithm to determine the order in which |
"Non-obvious" to the novice that this technique can be used, and non- I'm envisioning key functions that return long sequences of -1/0/1 Instead of removing cmp, I'd suggest simply placing a note in the |
FWIW, an object with a complex element-to-element comparison can define |
I know, but I don't always want to define the comparison on the object |
I am not sure I understand the reasoning behind removing the cmp I understand removing redundant features from a language, but I just |
Can someone provide a code sample to make this argument more I'm not sure what the 2to3 example (I presume you mean msg59937) shows Also, for all of you asking for cmp back, I hope you realize that |
FWIW, we had a long discussion on comp.lang.python and the net result Also, it was pointed-out the removal of cmp-functions in sorted() and In converting code from 2-to-3, we have found two sticky cases. The first occurs when an API had exposed cmp functions to the end-user The second case occurs when a primary key is sorted ascending and a s.sort(key=secondary, reverse=True)
s.sort(key=primary)
# now sorted by primary ascending, secondary descending That technique is going to be documented in an update of the sorting |
Tom, I think I'm missing your point: all three of the examples you give def direction(pt1, pt2):
"""angle of line segment from point 1 to point 2"""
return atan2(pt2.y - pt1.y, pt2.x - pt1.x)
my_points.sort(key=lambda pt: direction(reference_pt, pt)) ? How would having a cmp keyword argument make this any easier or Here's the best example I can think of for which key-based sorting is |
Mark: I think your example actually helps illustrate my point. My point was from functools import partial
from random import random
def turn(p, q, r):
"""Return -1, 0, or 1 if p,q,r forms a right, straight, or left turn
respectively."""
return cmp((q[0] - p[0])*(r[1] - p[1]) - (r[0] - p[0])*(q[1] - p[1]), 0)
pts = [(random(), random()) for i in xrange(10)]
i = min(xrange(len(pts)), key=lambda i: pts[i])
p = pts.pop(i)
pts.sort(cmp=partial(turn, p)) Here our comparison function requires only 2 multiplications and 5 On Sun, Dec 6, 2009 at 6:57 AM, Mark Dickinson <report@bugs.python.org>wrote:
|
Ah. Thanks for the explanation; I see your point. I guess you do just Though for this *particular* example, it seems to me that you could still use a key function lambda q: (q[0] - p[0])/(q[1]-p[1]), which would be even more efficient. This is assuming that your extreme It would be interesting to see some relative timings for the sort stage of |
If the equal min y-coords are handled, I think it'd be quicker too. As Guido Now, I understand cmp on the whole was removed from the language. Using |
Python's sort implementation is carefully written to only use the "<" |
I have a tree: A which is implemented as a dict tree = {
'A': set(['B', 'C']),
'B': set(['D', 'E']),
'C': set(),
'D': set(),
'E': set(),
} I want to sort the nodes. and I don't know how to write a key function for sort() in this situation so I write a cmp function: sorted(tree, cmp=lambda x, y: 1 if x in tree[y] else -1 if y in tree[x] else 0) and it gets ['A', 'C', 'B', 'E', 'D']. how to convert cmp to key really confused me and it surely need more typing time. so I disagree the removal |
That cmp function is nonsense and isn't even close to being correct: >>> from random import shuffle
>>> for i in range(10):
... t = list(tree)
... shuffle(t)
... print sorted(t, cmp=lambda x, y: 1 if x in tree[y] else -1 if y in tree[x] else 0)
['E', 'C', 'B', 'D', 'A']
['A', 'D', 'C', 'B', 'E']
['C', 'B', 'E', 'D', 'A']
['E', 'D', 'A', 'C', 'B']
['A', 'B', 'D', 'E', 'C']
['D', 'A', 'E', 'C', 'B']
['C', 'D', 'A', 'B', 'E']
['A', 'C', 'B', 'D', 'E']
['A', 'C', 'B', 'E', 'D']
['A', 'C', 'B', 'D', 'E']
Just cut and paste the recipe. Simple. |
Sorry I ripped the code from a mess and I forget the tree is "leaflized" as tree = {
'A': set(['B', 'C', 'D', 'E']),
'B': set(['D', 'E']),
'C': set(),
'D': set(),
'E': set(),
} I don't want to talk about the actual problem. I think sometime Thanks for reply. |
cmp is gone. It's chances of coming back are close enough to zero that an assertAlmostEqual test will pass :). The rest of the discussion should move to one of the general python lists. |
Shame on me, after a long time I realized the problem referenced in my old post (http://bugs.python.org/msg102019) was actually topological sorting. It can't be done by Python's sort(), which doesn't support partial order. Trying to use cmp parameter is completely wrong. And cmp would mislead people like me to sort a partial order, evil! Now I'm absolutely agree with gone of cmp, viva Raymond Hettinger! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: