按鍵功能只執行一次每個值,產生(keyvalue, value)
對;這是用來排序和稍後只是值排序順序返回。這有時稱爲Schwartzian transform。
您可以自己測試;您可以計算函數被調用的頻率,例如:
>>> def keyfunc(value):
... keyfunc.count += 1
... return value
...
>>> keyfunc.count = 0
>>> sorted([0, 8, 1, 6, 4, 5, 3, 7, 9, 2], key=keyfunc)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> keyfunc.count
10
或者您可以收集所有傳入的值;你會看到,他們按照原來的輸入順序:
>>> def keyfunc(value):
... keyfunc.arguments.append(value)
... return value
...
>>> keyfunc.arguments = []
>>> sorted([0, 8, 1, 6, 4, 5, 3, 7, 9, 2], key=keyfunc)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> keyfunc.arguments
[0, 8, 1, 6, 4, 5, 3, 7, 9, 2]
如果你想讀的CPython的源代碼,相關函數被調用listsort()
,並keyfunc
在下面的循環使用(saved_ob_item
是輸入陣列),其在執行之前排序發生:
for (i = 0; i < saved_ob_size ; i++) {
keys[i] = PyObject_CallFunctionObjArgs(keyfunc, saved_ob_item[i],
NULL);
if (keys[i] == NULL) {
for (i=i-1 ; i>=0 ; i--)
Py_DECREF(keys[i]);
if (saved_ob_size >= MERGESTATE_TEMP_SIZE/2)
PyMem_FREE(keys);
goto keyfunc_fail;
}
}
lo.keys = keys;
lo.values = saved_ob_item;
所以最後,有兩個陣列,一個與keys
和一個與原來的值。所有排序操作並行處理這兩個數組,並對lo.keys
中的值進行排序,並將lo.values
中的元素串聯起來。
由於性能方面的原因,'key ='與''cmp =''較早的'cmp ='的整個*點是爲了減少調用次數。如果它每次都運行計算,它將比* cmp'方法取代更多的*函數調用,所以它不可能成功實現其設計目標。 –