带lambda的min总是返回python中的第一个值吗?

时间:2015-01-15 01:48:32

标签: python lambda

在python 2.7.3中,使用带有lambda的min函数,例如min(list, key=f),其中f是lambda函数。如果f(x)列表中的所有x的值始终相同,是否可以保证会返回list[0]

由于

2 个答案:

答案 0 :(得分:5)

在CPython和PyPy中是的。您可以在source code中看到maxval仅在当前值低于maxval时才会更新。请注意,在CPython内部,min_maxmin()使用了相同的函数(mix()),唯一的区别是op passed是两种情况:for {{1它是minPy_LT max

Py_GT

Same case with PyPymaxitem = 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); } } } w_max_item仅在项目是序列中的第一项或者根据基于{的值选择的函数满足条件时更新{1}}(&#34; max&#34;或&#34; min&#34;):

w_max_val

答案 1 :(得分:0)

正如Ashwini在他的出色回答中写道的那样,CPython的实现是这样的,即在平局的情况下将返回第一个结果。在Python 3.4 documentation中,明确说明了这种行为:

  

如果多个项目最小,则该函数返回第一个项目   遇到。这与其他排序稳定性保持一致   排序(iterable,key = keyfunc)[0]和heapq.nsmallest(1,   iterable,key = keyfunc)。

不幸的是,在Python 2文档中没有这样的声明:就文档而言,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上使用它取决于您对严格遵守已定义和记录的行为的重视程度。