在python中,带lambda的min是否总是返回第一个值?
在python 2.7.3中,将min函数与lambda一起使用,例如在python中,带lambda的min是否总是返回第一个值?,python,lambda,Python,Lambda,在python 2.7.3中,将min函数与lambda一起使用,例如min(list,key=f)其中f是lambda函数。如果列表中所有x的f(x)值始终相同,是否保证返回list[0] 谢谢你在CPython和PyPy中所说的是的。在中可以看到,maxval仅当当前值低于maxval时才会更新。请注意,在CPython内部,相同的函数(min\u max)同时用于min()和mix(),唯一的区别是两者的情况:对于min它是Py\u LT,对于max它是Py\u GT maxitem =
min(list,key=f)
其中f
是lambda函数。如果列表中所有x
的f(x)
值始终相同,是否保证返回list[0]
谢谢你在CPython和PyPy中所说的是的。在中可以看到,
maxval
仅当当前值低于maxval
时才会更新。请注意,在CPython内部,相同的函数(min\u max
)同时用于min()
和mix()
,唯一的区别是两者的情况:对于min
它是Py\u LT
,对于max
它是Py\u GT
maxitem = NULL; /* the result */
maxval = NULL; /* the value associated with the result */
while (( item = PyIter_Next(it) )) {
/* get the value from the key function */
if (keyfunc != NULL) {
val = PyObject_CallFunctionObjArgs(keyfunc, item, NULL);
if (val == NULL)
goto Fail_it_item;
}
/* no key function; the value is the item */
else {
val = item;
Py_INCREF(val);
}
/* maximum value and item are unset; set them */
if (maxval == NULL) {
maxitem = item;
maxval = val;
}
/* maximum value and item are set; update them as necessary */
else {
int cmp = PyObject_RichCompareBool(val, maxval, op);
if (cmp < 0)
goto Fail_it_item_and_val;
else if (cmp > 0) {
Py_DECREF(maxval);
Py_DECREF(maxitem);
maxval = val;
maxitem = item;
}
else {
Py_DECREF(item);
Py_DECREF(val);
}
}
}
正如Ashwini在其出色的回答中所写的那样,CPython的实现使得第一个结果将在平局时返回。在中,明确说明了此行为: 如果多个项目最少,则函数返回第一个项目 遇到。这与其他保持稳定性的排序一致 工具,如排序(iterable,key=keyfunc)[0]和heapq.nsmallest(1, iterable,key=keyfunc) 不幸的是,Python2文档中没有这样的语句:
min
遇到多个最小项时的行为在文档中是未定义的。这意味着CPython解释器不能保证这种行为在将来的版本中会出现,尽管有人可能会说,由于这种功能是众所周知的,而且已经建立起来了,所以它实际上是语言的一个方面
如果您希望非常仔细和明确,可以根据Python 2 API定义一个保证找到第一个最小值的函数:
def first_min(iterable, **kwargs):
wrapped = ((x,i) for i,x in enumerate(x))
if "key" in kwargs:
keyfun = kwargs["key"]
kwargs["key"] = lambda x: (keyfun(x[0]), x[1])
return min(wrapped, **kwargs)[0]
您是否在内置的
min
上使用它取决于您对遵守已定义和记录的行为的重视程度。可能?取决于min
的实现。这真的很重要吗,因为您已经根据它们都相等这一事实对示例进行了预测?在我的程序中,这很重要,它与代码的特定功能有关。尽管如此,我还是想知道这是否属实。@HunterMcMillen,f(0)==f(1)
但可能是l[0]!=l[1]
@omega,我在解释亨特米伦为什么它可能很重要。几乎是CPython
的复制品?。我正在使用的python是在linux机器上。@omega它是python的一个实现(默认值)。鉴于这是一个未记录的事实,我们是否应该避免编写假定CPython以这种方式运行的python代码?我怀疑实现是否会以某种方式改变,从而破坏这种行为(到目前为止,它实际上是API的一部分),但我想这不是一种保证。啊!在Python2中,这是未记录的,但在Python3.4中,我们有:“如果多个项是最小的,则函数返回遇到的第一个项。”
def first_min(iterable, **kwargs):
wrapped = ((x,i) for i,x in enumerate(x))
if "key" in kwargs:
keyfun = kwargs["key"]
kwargs["key"] = lambda x: (keyfun(x[0]), x[1])
return min(wrapped, **kwargs)[0]