python-2.7functionparametersfunction-callscmp

Why deos a two parameter funnction within sort() method runs without parameters and why does that function should have two parameters?


The following code block gives ['AAB', 'BBC', 'EFM', 'CNN', 'ESPN', 'ITN', 'XYZ'] as the output. But the MyCmp() function that is inside the sort() method does not have any parameters .If I created a function that takes exactly one parameter and did call it inside the sort() method, it gives an error message telling "TypeError: MyCmp() takes exactly 1 argument (2 given)"

Can anybody explain the reason for this? Why does that MyCmp() function does not need to be given any parameters like in a normal function call?

A = ['ESPN','BBC','AAB','XYZ','CNN','ITN','EFM']

def MyCmp(a,b):
    return cmp(a[1],b[1])
A.sort(MyCmp)

print A

When I added print a,b line to the function. It outputs

BBC ESPN
AAB BBC
XYZ AAB
XYZ BBC
XYZ ESPN
CNN ESPN
CNN BBC
ITN CNN
ITN XYZ
ITN ESPN
EFM ESPN
EFM BBC
EFM CNN

Solution

  • When you do A.sort(MyCmp), you're passing MyCmp as an argument to A.sort. You're not calling MyCmp at all yourself. Instead, that's something the implementation of sort will do while it runs. Because of how list.sort works, it will provide two arguments when it makes those actual calls.

    You can write your own code that treats functions as first-class objects. For instance, here's a function that calls a function you pass it as an argument twice (with no arguments):

    def call_twice(some_function):
        some_function()
        some_function()
    

    There are lots of situations where it's handy to be able to pass functions around (callbacks, decorators). If you're just starting to learn Python, you may not need those things immediately, but do expect that you'll learn about them sooner or later.

    Note that using a cmp function for sorting is deprecated. In Python 3, the only way to customize a sort is by using a key function (which takes only one argument). You can also use a key function in the more recent versions of Python 2, so if you want to write forwards compatible code, you should go that route. Starting in Python 3.2, you can use functools.cmp_to_key to create a key function from an older cmp function. The docs offer an implementation of the function you can use in older Python versions. But I'd just stay away from cmp in new code.