理解__call__和list.sort(键)

时间:2021-10-04 07:41:09

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 have understood, __call__ is what is called when object() is called - calling the object as a function.

谁能解释一下这是如何工作的?据我所知,__ call__是调用object()时调用的函数 - 将对象作为函数调用。

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

我不明白的是nums.sort(key = DistanceFrom(10))。这个怎么用?有人可以解释这一行吗?

Thanks!

5 个解决方案

#1


7  

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

在这里,我定义了一个函数DistanceFrom(),它可以以类似于你的类的方式使用,但可能更容易理解

>>> 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

因此,您会看到DistanceFrom返回的对象为每个nums项调用一次,然后根据返回的值对nums进行排序

#2


8  

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

python中的__call__允许类运行,就像它是一个函数一样。您可以手动尝试:

>>> 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.

对于列表中的每个项目调用该函数是什么类型,并使用返回的值作为排序键。在这个示例中,您将获得一个列表,其中第一个项目最接近10,而另一个项目更靠近末尾。

#3


4  

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.

它使用关键函数对象DistanceFrom(10)对列表num进行排序。它需要是可调用的,因为密钥需要可调用。结果输出按其“远程”从10开始排序,即9是最接近10的值,101是最远的值。

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.

在初始化对象并将其作为关键参数传递给sort方法之后,在每次迭代时,将使用当前值(即x是什么)调用它,并且返回值将用于确定结果列表中x的位置。

#4


1  

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.

当你打电话的时候意味着你希望它返回一个值。当您创建一个定义了__call__方法的类时,您要求该类的实例可以像函数一样运行。

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:

至于排序的关键参数,这里是您直接从Python文档中解释的:

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)

key指定一个参数的函数,该函数用于从每个列表元素中提取比较键:key = str.lower。默认值为None(直接比较元素)

#5


1  

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

每当我发现我不理解基础知识时,Python文档都非常好。我找到这些与谷歌。

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=.

关键参数是sort将调用列表元素的函数。我通过googling sort site找到了这个doc:http://docs.python.org/然后搜索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__.

__call__是一个可以添加到对象的函数,使该对象可以调用,就好像它是一个函数一样。我通过googling __call__ site:http://docs.python.org/找到了这个文档,然后点击了__call__文档的链接。

#1


7  

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

在这里,我定义了一个函数DistanceFrom(),它可以以类似于你的类的方式使用,但可能更容易理解

>>> 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

因此,您会看到DistanceFrom返回的对象为每个nums项调用一次,然后根据返回的值对nums进行排序

#2


8  

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

python中的__call__允许类运行,就像它是一个函数一样。您可以手动尝试:

>>> 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.

对于列表中的每个项目调用该函数是什么类型,并使用返回的值作为排序键。在这个示例中,您将获得一个列表,其中第一个项目最接近10,而另一个项目更靠近末尾。

#3


4  

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.

它使用关键函数对象DistanceFrom(10)对列表num进行排序。它需要是可调用的,因为密钥需要可调用。结果输出按其“远程”从10开始排序,即9是最接近10的值,101是最远的值。

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.

在初始化对象并将其作为关键参数传递给sort方法之后,在每次迭代时,将使用当前值(即x是什么)调用它,并且返回值将用于确定结果列表中x的位置。

#4


1  

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.

当你打电话的时候意味着你希望它返回一个值。当您创建一个定义了__call__方法的类时,您要求该类的实例可以像函数一样运行。

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:

至于排序的关键参数,这里是您直接从Python文档中解释的:

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)

key指定一个参数的函数,该函数用于从每个列表元素中提取比较键:key = str.lower。默认值为None(直接比较元素)

#5


1  

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

每当我发现我不理解基础知识时,Python文档都非常好。我找到这些与谷歌。

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=.

关键参数是sort将调用列表元素的函数。我通过googling sort site找到了这个doc:http://docs.python.org/然后搜索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__.

__call__是一个可以添加到对象的函数,使该对象可以调用,就好像它是一个函数一样。我通过googling __call__ site:http://docs.python.org/找到了这个文档,然后点击了__call__文档的链接。