考虑有一个像这样定义的对象列表:
class MyItem:
def __init__(self):
self.count = 0
def increase(self):
self.count += 1
def decrease(self):
self.count -=1
def get_count(self):
return self.count
all_objects = []
for i in range(10):
all_objects.append(MyItem())
在程序的各个部分,会调用increase
和decrease
方法。现在你想找到计数最多的项,但max
函数并不知道对象实现的细节。因此,你需要让它知道使用哪个函数来评估它们之间的项。在这种情况下,这将是项的get_count
方法,你可以像这样调用max
:
max(all_objects, key=lambda x: x.get_count)
基本上,一个“键”是排序的“推理器”,是用于比较的值。
为了更好地理解它,请考虑每次调用像这样的整数列表:
some_list = [1,2,3]
max(some_list)
将其作为未修改值提供密钥与提供其作为键相同:
some_list = [1,2,3]
max(some_list, key=lambda x:x)
更新
作者问道:
我可以将布尔值合并到键元素中吗?
因此,我正在扩展我的答案以回复。
简而言之,答案是:可以。但在实践中,这几乎没有任何用处。至于解释,请考虑以下情况:
my_list = [True, False, False, True, False, False, False]
max(my_list)
结果显然是True,因为约定True > False。但问题是,返回哪个True对象(请记住,Python中的
everything都是对象,即使是布尔类型也是如此)?是第一个还是第二个?这取决于
max
的内部实现方式。由于这一点,我们没有这个应用的实际用途。(顺便说一句,
max
被实现为返回第一个,但这在这个时候并不关系我们。)
重要提示:上面的示例是一个简化版,假设两个True
对象实际上是两个不同的对象,这是不正确的。在Python中,它们实际上是相同的对象,正如评论中@mu無所指出的那样。将其视为一个粗略的示例,有关更相关的示例,请继续阅读。
但让我们来看看这在我们之前的示例中的行为:
class MyItem:
def __init__(self, id):
self.count = 0
self._bool = bool(random.randrange(2))
self.id = id
def increase(self):
self.count += 1
def decrease(self):
self.count -=1
def get_count(self):
return self.count
def get_bool(self):
return self._bool
我们只添加了三个东西,一个用于识别对象的
id
,一个私有属性
_bool
和一个
getter 函数
get_bool
作为
key
使用。让我们创建一个这样的对象列表并进行一些随机增量以区分它们:
import random
all_objects = []
for i in range(10):
new_obj = MyItem(i)
for k in range(random.randrange(10)):
new_obj.increase()
all_objects.append(new_obj)
此时,我们有一个名为
all_objects
的列表,其中包含10个具有随机值的
MyItem
对象,在它们的
count
属性中以及一个随机的
boolean
值在它们的
_bool
属性中。
现在让我们看看当我们尝试对其进行排序时会发生什么。首先,我们将打印出所有这些对象,这样更容易得出结论。我将显示三个连续的结果作为列以保留空间。
def print_object(obj):
print "id: {0} count: {1} _bool: {2}".format(o.id, o.get_count(), o.get_bool())
for o in all_objects: print_object(o)
print "-"*27
max_obj = max(all_objects, key=lambda x:x.get_bool())
print_object(max_obj)
输出:
id: 0 count: 1 _bool: False id: 0 count: 2 _bool: False id: 0 count: 1 _bool: False
id: 1 count: 7 _bool: True id: 1 count: 3 _bool: False id: 1 count: 4 _bool: False
id: 2 count: 0 _bool: False id: 2 count: 1 _bool: False id: 2 count: 2 _bool: False
id: 3 count: 5 _bool: False id: 3 count: 4 _bool: False id: 3 count: 1 _bool: True
id: 4 count: 4 _bool: False id: 4 count: 6 _bool: False id: 4 count: 9 _bool: False
id: 5 count: 4 _bool: False id: 5 count: 6 _bool: False id: 5 count: 3 _bool: False
id: 6 count: 7 _bool: True id: 6 count: 4 _bool: False id: 6 count: 5 _bool: False
id: 7 count: 8 _bool: True id: 7 count: 7 _bool: True id: 7 count: 1 _bool: True
id: 8 count: 1 _bool: True id: 8 count: 8 _bool: False id: 8 count: 9 _bool: False
id: 9 count: 7 _bool: True id: 9 count: 4 _bool: False id: 9 count: 1 _bool: False
--------------------------- --------------------------- ---------------------------
id: 1 count: 7 _bool: True id: 7 count: 7 _bool: True id: 3 count: 1 _bool: True
从输出结果中,我们可以清晰地看到该函数返回了第一个带有
_bool
属性且值为
True
的项目。这几乎不是任何重要事物的
max
值...