在python中,带lambda的min是否总是返回第一个值?

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

在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 = 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]