簡體   English   中英

帶lambda的min總是返回python中的第一個值嗎?

[英]Does min with lambda always return the first value in python?

在python 2.7.3中,使用帶有lambda的min函數,例如min(list, key=f) ,其中f是lambda函數。 如果f(x)始終是列表中所有x的相同值,是否保證將返回list[0]

謝謝

在CPython和PyPy中是的。 你可以在看到源代碼maxval只有當電流值大於下被更新maxval 注意,在CPython內部,同一函數( min_max )用於min()mix() ,唯一的區別是傳遞op是兩種情況:對於min它是Py_LT而對於max它是Py_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);
        }
    }
}

與PyPy相同的情況下w_max_itemw_max_val僅在項目是序列中的第一個項目時更新,或者如果它滿足根據implementation_of (“max”或“min”)的值選擇的函數的條件:

if not has_item or \
        space.is_true(compare(w_compare_with, w_max_val)):
    has_item = True
    w_max_item = w_item
    w_max_val = w_compare_with

正如Ashwini在他的出色回答中所寫的那樣,CPython的實現使得第一個結果將在平局的情況下返回。 Python 3.4文檔中 ,明確說明了此行為:

如果多個項目是最小的,則該函數返回遇到的第一個項目。 這與其他排序穩定性保留工具(如sorted(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使用它取決於您對嚴格遵守已定義和記錄的行為的重視程度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM