473,404 Members | 2,114 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

python 3: sorting with a comparison function

Does Python 3 have no way anymore to sort with a comparison function?

Both [].sort() and sorted() seem to accept only 'key' and 'reverse' arguments,
the 'cmp' argument seems to be gone. Can that be?

Thomas
Oct 9 '08 #1
11 21997
Thomas Heller:
the 'cmp' argument seems to be gone. Can that be?
Yes, that's a wonderful thing, because from the code I see around
99.9% of people see the cmp and just use it, totally ignoring the
presence of the 'key' argument, that allows better and shorter
solutions of the sorting problem. So removing the cmp is the only way
to rub the nose of programmers on the right solution, and it goes well
with the Python "There should be one-- and preferably only one --
obvious way to do it.".

For most of very uncommon situations where key isn't the right thing,
you can use this code by Hettinger:

def cmp2key(mycmp):
"Converts a cmp= function into a key= function"
class K:
def __init__(self, obj, *args):
self.obj = obj
def __cmp__(self, other):
return mycmp(self.obj, other.obj)
return K
s.sort(key=cmp2key(lambda p, q: cmp(p.lower(), q.lower())))

That code can't be used in one situation: when the array to be sorted
is huge, that situation can be handled by the original true cmp
function, but not by that cmp2key(). But I have met such situation so
far. When you have an huge amount of data, use an external sort, even
Windows has one, even if its usage is a bit tricky (linux sort command
is safer).

Bye,
bearophile
Oct 9 '08 #2
Thomas Heller wrote:
Does Python 3 have no way anymore to sort with a comparison function?

Both [].sort() and sorted() seem to accept only 'key' and 'reverse' arguments,
the 'cmp' argument seems to be gone. Can that be?
Yes. When this was discussed, no one could come up with an actual use
case in which the compare function was not based on a key function.
Calling the key function n times has to be faster than calling a compare
function n to O(nlogn) times with 2 keys computed for each call. The
main counter argument would be if there is no room in memory for the
shadow array of key,index pairs. And that can be at least sometimes
handled by putting the original on disk and sorting an overt key,index
array. Or by using a database.

Oct 9 '08 #3
Thomas Heller wrote:
>Does Python 3 have no way anymore to sort with a comparison function?

Both [].sort() and sorted() seem to accept only 'key' and 'reverse' arguments,
the 'cmp' argument seems to be gone. Can that be?
Terry Reedy schrieb:
Yes. When this was discussed, no one could come up with an actual use
case in which the compare function was not based on a key function.
Calling the key function n times has to be faster than calling a compare
function n to O(nlogn) times with 2 keys computed for each call. The
main counter argument would be if there is no room in memory for the
shadow array of key,index pairs. And that can be at least sometimes
handled by putting the original on disk and sorting an overt key,index
array. Or by using a database.
be************@lycos.com schrieb:
Yes, that's a wonderful thing, because from the code I see around
99.9% of people see the cmp and just use it, totally ignoring the
presence of the 'key' argument, that allows better and shorter
solutions of the sorting problem. So removing the cmp is the only way
to rub the nose of programmers on the right solution, and it goes well
with the Python "There should be one-- and preferably only one --
obvious way to do it.".

Thanks, I got it now.

Thomas
Oct 10 '08 #4
On 9 Okt., 22:36, bearophileH...@lycos.com wrote:
Yes, that's a wonderful thing, because from the code I see around
99.9% of people see the cmp and just use it, totally ignoring the
presence of the 'key' argument, that allows better and shorter
solutions of the sorting problem.
Me too because I don't get this:

"key specifies a function of one argument that is used to extract a
comparison key from each list element: key=str.lower. The default
value is None."

Kay
Oct 10 '08 #5
On Oct 10, 8:35 am, Kay Schluehr <kay.schlu...@gmx.netwrote:
On 9 Okt., 22:36, bearophileH...@lycos.com wrote:
Yes, that's a wonderful thing, because from the code I see around
99.9% of people see the cmp and just use it, totally ignoring the
presence of the 'key' argument, that allows better and shorter
solutions of the sorting problem.

Me too because I don't get this:

"key specifies a function of one argument that is used to extract a
comparison key from each list element: key=str.lower. The default
value is None."

Kay
Don't know if further explanation is needed, but here is the deal:

cmp is a function that receives two values and you return -1, 0 or 1
depending if the first is smaller, equal or bigger. 99% of the time
you will do some operation on the values that come in and then do a if
statement with ">" or "<" and return -1,0,1.

key is a function that receives one value and you return the value
that you would normally compare against.

Let me show an example:
>>data=[(4,'v'),(2,'x'),(1,'a')]
sorted(data)
[(1, 'a'), (2, 'x'), (4, 'v')]

OK, we sorted the data, but What if we want to sort by the letter
instead of the number? Let's use cmp:
>>def comp(x, y):
key_of_x=x[1]
key_of_y=y[1]
if key_of_x < key_of_y:
return -1
elif key_of_x key_of_y:
return 1
else:
return 0 #key_of_x == key_of_y
>>sorted(data,cmp=comp)
[(1, 'a'), (4, 'v'), (2, 'x')]

Very well, so how do we do this using key?
>>def keyfunc(x):
key_of_x=x[1]
return key_of_x
>>sorted(data,key=keyfunc)
[(1, 'a'), (4, 'v'), (2, 'x')]
Same output. Very good.

(Of course a smart python developer would use the operator module so
he doesn't even have to write keyfunc but this was just an example)

In summary to transform most cmp functions to a key function you just
take the code that calculates the first value to be compared and leave
out the rest of the logic.

Hope that was helpful.
Oct 10 '08 #6
Kay Schluehr:
Sometimes it helps when people just make clear how they use technical
terms instead of invoking vague associations.
And generally Python docs can enjoy growing few thousands examples...

Bye,
bearophile
Oct 10 '08 #7
On Oct 10, 12:22*pm, prueba...@latinmail.com wrote:
On Oct 10, 8:35 am, Kay Schluehr <kay.schlu...@gmx.netwrote:
On 9 Okt., 22:36, bearophileH...@lycos.com wrote:
Yes, that's a wonderful thing, because from the code I see around
99.9% of people see the cmp and just use it, totally ignoring the
presence of the 'key' argument, that allows better and shorter
solutions of the sorting problem.
Me too because I don't get this:
"key specifies a function of one argument that is used to extract a
comparison key from each list element: key=str.lower. The default
value is None."
Kay

Don't know if further explanation is needed, but here is the deal:

cmp is a function that receives two values and you return -1, 0 or 1
depending if the first is smaller, equal or bigger. 99% of the time
you will do some operation on the values that come in and then do a if
statement with ">" or "<" and return -1,0,1.

key is a function that receives one value and you return the value
that you would normally compare against.

Let me show an example:
>data=[(4,'v'),(2,'x'),(1,'a')]
sorted(data)

[(1, 'a'), (2, 'x'), (4, 'v')]

OK, we sorted the data, but What if we want to sort by the letter
instead of the number? Let's use cmp:
>def comp(x, y):

* * * key_of_x=x[1]
* * * key_of_y=y[1]
* * * if key_of_x < key_of_y:
* * * * return -1
* * * elif key_of_x key_of_y:
* * * * return 1
* * * else:
* * * * return 0 #key_of_x == key_of_y
>sorted(data,cmp=comp)

[(1, 'a'), (4, 'v'), (2, 'x')]

Very well, so how do we do this using key?
>def keyfunc(x):

* * * key_of_x=x[1]
* * * return key_of_x
>sorted(data,key=keyfunc)

[(1, 'a'), (4, 'v'), (2, 'x')]

Same output. Very good.

(Of course a smart python developer would use the operator module so
he doesn't even have to write keyfunc but this was just an example)
IIRC, the return values are not limited to -1, 0, and 1, but are more
like "any value less than 0", 0, and "any value greater than 0". This
allows you to implement numeric cmp routines as:

def cmp(x,y):
return x-y

or just:

cmp = lambda x,y: x-y

-- Paul
Oct 10 '08 #8
On 10 Okt., 20:38, bearophileH...@lycos.com wrote:
Kay Schluehr:
Sometimes it helps when people just make clear how they use technical
terms instead of invoking vague associations.

And generally Python docs can enjoy growing few thousands examples...
Cleaning up and extending documentation is a large community effort
that requires an informational PEP for guidelines and management
support by the python-dev leads. The official documentation is ad hoc
and just about better than nothing. A Python documentation guideline
might also have positive impact on 3rd party package authors like us.

Generally Python has become a very well managed project. I hope the
docs as well as the stdlib will become the major concerns of Python
3.1.
Oct 10 '08 #9
be************@lycos.com schrieb:
Kay Schluehr:
>Sometimes it helps when people just make clear how they use technical
terms instead of invoking vague associations.

And generally Python docs can enjoy growing few thousands examples...
Well, that may not be necessary. But I think that a clear example how to use
the 'key=' parameter in the sort() and sorted() method/function is badly needed.

Thomas
Oct 10 '08 #10
Kay Schluehr wrote:
Me too because I don't get this:

"key specifies a function of one argument that is used to extract a
comparison key from each list element: key=str.lower. The default
value is None."
I am not sure what you do not get, but it should say 'for example,
key=str.lower." None is the default value of key.

Oct 10 '08 #11
On 10 Okt., 23:04, Terry Reedy <tjre...@udel.eduwrote:
Kay Schluehr wrote:
Me too because I don't get this:
"key specifies a function of one argument that is used to extract a
comparison key from each list element: key=str.lower. The default
value is None."

I am not sure what you do not get, but it should say 'for example,
key=str.lower." None is the default value of key.
See the discussion above.
Oct 10 '08 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

40
by: Xah Lee | last post by:
is it possible in Python to create a function that maintains a variable value? something like this: globe=0; def myFun(): globe=globe+1 return globe
11
by: David Rasmussen | last post by:
I want to use sort() and supply my own comparison function, like bool lessThan(const S& a, const S& b) { return value(a) < value(b); } and then sort by: sort(a.begin(), a.end(), lessThan);
6
by: aurgathor | last post by:
Howdy, How do I pass some function a generic comparison function? I figured out one non-generic case, but since this code got parameter declarations in two places, it's obviously not generic....
14
by: Spoon | last post by:
Hello, I've come across the following comparison function used as the 4th parameter in qsort() int cmp(const void *px, const void *py) { const double *x = px, *y = py; return (*x > *y) -...
2
by: eastern_strider | last post by:
I'm running into problems about defining a comparison function for a map which has a user defined key. For example: class Key { public: string name; int number; Key (na, nu) : name (na),...
0
by: SvenMathijssen | last post by:
Hi, I've been wrestling with a problem for some time that ought to be fairly simple, but turns out to be very difficult for me to solve. Maybe someone here knows the answer. What I try to do is...
5
by: fade | last post by:
Good afternoon, I need some advice on the following: I've got a class that has a member std::vector<CStringm_vFileName and a member CString m_path; The vector contains a bunch of filenames with...
18
by: PicO | last post by:
how can i make a set with comparison function ? all i know that i can make a map with comparison function like this struct strCmp { bool operator()( const char* s1, const char* s2 ) const {...
3
by: laredotornado | last post by:
Hi, I'm using php 4.4.4. Given two variables, $dir1 = "/usr/local/apache2/htdocs/" $dir2 = "/usr/local/apache2/htdocs" What is a comparison function I could write that would say these two...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.