开发者

Understanding __call__ and list.sort(key)

开发者 https://www.devze.com 2023-01-22 01:14 出处:网络
I have the following code I am trying to understand: >>> class DistanceFrom(object): def __init__(self, origin):

I have the following code I am trying to understand:

>>> class DistanceFrom(object):
        def __init__(self, origin):
            self.origin = origin
        def __call__(self, x):
            return abs(x - self.origin)  

>>> nums = [1, 37, 42, 101, 13, 9, -20]
>>> nums.sort(key=DistanceFrom(10))
>>> nums
[9, 13, 1, 37, -20, 42, 101]

Can anyone explain how this works? As far as I ha开发者_JS百科ve understood, __call__ is what is called when object() is called - calling the object as a function.

What I don't understand is how nums.sort(key=DistanceFrom(10)). How does this work? Can anyone please explain this line?

Thanks!


__call__ in python allows a class to be run as if it's a function. You can try this out manually:

>>> dis = DistanceFrom(10)
>>> print dis(10), dis(5), dis(0)
0 5 10
>>> 

What sort does is call that function for every item in your list and uses the returned value as sort key. In this example you'll get a list back with the items closest to 10 first, and the one further away more towards the end.


Here I have defined a function DistanceFrom() which can be used in a similar way to your class, but might be easier to follow

>>> def DistanceFrom(origin):
...     def f(x):
...         retval = abs(x - origin)
...         print "f(%s) = %s"%(x, retval)
...         return retval
...     return f
... 
>>> nums = [1, 37, 42, 101, 13, 9, -20]
>>> nums.sort(key=DistanceFrom(10))
f(1) = 9
f(37) = 27
f(42) = 32
f(101) = 91
f(13) = 3
f(9) = 1
f(-20) = 30
>>> nums
[9, 13, 1, 37, -20, 42, 101]

So you see that the object returned by DistanceFrom is called once for each item of nums and then nums is returned sorted in accordance with the returned values


It sorts list nums in place using a key function object DistanceFrom(10). It needs to be callable because key needs to be callable. The resulting output is sorted by their "remoteness" from 10, that is 9 is the closest value to 10, 101 is the farthest one.

After the object is initialised and passed as a key parameter to the sort method, on each iteration it will be called with the current value (that's what x is) and returned value would be used to determine x's position in the resulting list.


When you call something that means you are expecting it to return a value. When you create a class that has the __call__ method defined, you are dictating that an instance of that class can behave as a function does.

For the purpose of this question, this:

class DistanceFrom(object):
        def __init__(self, origin):
            self.origin = origin
        def __call__(self, x):
            return abs(x - self.origin) 

Is functionally equivalent to:

def distance_from(origin, other):
    return abs(other - origin)

As for the key argument to sort, here is your explanation straight from the Python documentation:

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 (compare the elements directly)


The Python docs are quite good whenever I find I don't understand the fundamentals. I located these with google.

The key parameter is a function that sort will call on the elements of the list. I located this doc by googling sort site:http://docs.python.org/ and then searching for key=.

__call__ is a function you can add to an object to make that object callable as if it were a function. I found this doc by googling __call__ site:http://docs.python.org/ and then following the link to the doc for __call__.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号