sorted
内建函数有key
关键字专用参数.大多数自定义实现都类似于堆排序算法的以下实现
import heapq
import itertools
from typing import (Iterable,
TypeVar)
Domain = TypeVar('Domain')
def heapsort(iterable: Iterable[Domain]) -> Iterable[Domain]:
heap = []
for element in iterable:
heapq.heappush(heap, element)
for _ in itertools.repeat(None, len(heap)):
yield heapq.heappop(heap)
不支持key
参数。我想到了一个装饰器,它将在下一种方式中添加key
参数支持。
from functools import wraps
from operator import itemgetter
from typing import (Callable,
Iterable,
Optional,
TypeVar)
Domain = TypeVar('Domain')
Sortable = TypeVar('Sortable')
def with_key(plain: Callable[[Iterable[Sortable]], Iterable[Sortable]]
) -> Callable[..., Iterable[Domain]]:
@wraps(plain)
def implementation(iterable: Iterable[Domain],
*,
key: Optional[Callable[[Domain], Sortable]] = None
) -> Iterable[Domain]:
if key is None:
yield from plain(iterable)
return
yield from map(itemgetter(2),
plain((key(element), index, element)
for index, element in enumerate(iterable)))
return implementation
在那之后,就像
>>> heapsort_with_key = with_key(heapsort)
>>> list(heapsort_with_key(range(10), key=lambda x: -x))
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
我想知道是否有更好的方法(例如,在内存效率方面)添加key
参数?有人知道它是如何在sorted
中实现的吗?
发布于 2018-12-22 05:30:02
Python是开源的,GitHub存储库python/cpython中的所有源代码都是开源的。对于大量的内置程序,可以在cpython/Python/bltinmodule.c中找到它们。在当前的修订版中,排序函数定义的开始在第2175项中找到,实际的函数本身在第2201项中找到。
但是,我不确定了解排序的实现是否会对优化堆排序有太大帮助,因为排序使用蒂姆塞德。
我可以提出一个建议:装饰师总是会增加开销,尤其是在这种情况下,最好只是将关键参数与原始函数集成起来,但这个答案可能忽略了问题的全部要点。
https://codereview.stackexchange.com/questions/210160
复制