“ lambda”与“ operator.attrgetter('xxx')”作为排序键功能

“ lambda”与“ operator.attrgetter('xxx')”作为排序键功能,第1张

“ lambda”与“ operator.attrgetter('xxx')”作为排序键功能

当仅在

attrgetter('attributename')
和之间
lambda o:o.attributename
作为排序键进行选择时,则使用
attrgetter()
是两者中 较快的 选项。

请记住,在排序之前,键函数仅对列表中的每个元素应用一次,因此,为了进行比较,我们可以在时间试用中直接使用它们:

>>> from timeit import Timer>>> from random import randint>>> from dataclasses import dataclass, field>>> @dataclass... class Foo:...     bar: int = field(default_factory=lambda: randint(1, 10**6))...>>> testdata = [Foo() for _ in range(1000)]>>> def test_function(objects, key):...     [key(o) for o in objects]...>>> stmt = 't(testdata, key)'>>> setup = 'from __main__ import test_function as t, testdata; '>>> tests = {...     'lambda': setup + 'key=lambda o: o.bar',...     'attrgetter': setup + 'from operator import attrgetter; key=attrgetter("bar")'... }>>> for name, tsetup in tests.items():...     count, total = Timer(stmt, tsetup).autorange()...     print(f"{name:>10}: {total / count * 10 ** 6:7.3f} microseconds ({count} repetitions)")...    lambda: 130.495 microseconds (2000 repetitions)attrgetter:  92.850 microseconds (5000 repetitions)

因此,应用

attrgetter('bar')
1000次大约比a快40μs
lambda
。这是因为调用 Python
函数具有一定的开销,而不是调用诸如产生的原生函数
attrgetter()

这种速度优势也转化为更快的排序:

>>> def test_function(objects, key):...     sorted(objects, key=key)...>>> for name, tsetup in tests.items():...     count, total = Timer(stmt, tsetup).autorange()...     print(f"{name:>10}: {total / count * 10 ** 6:7.3f} microseconds ({count} repetitions)")...    lambda: 218.715 microseconds (1000 repetitions)attrgetter: 169.064 microseconds (2000 repetitions)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5655437.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存