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

我正在看一些使用比较函数进行很多排序调用的代码,似乎应该使用关键函数。

如果要更改seq.sort(lambda x,y: cmp(x.xxx, y.xxx)),则最好:

seq.sort(key=operator.attrgetter('xxx'))

要么:

seq.sort(key=lambda a:a.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次大约比lambda快40μs。这是因为调用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)

单行的'if'/'for'语句是否使用Python样式好? - python

我经常在这里看到某人的代码,看起来像是“单线”,这是一条单行语句,以传统的“if”语句或“for”循环的标准方式执行。我在Google周围搜索,无法真正找到可以执行的搜索类型?任何人都可以提出建议并最好举一些例子吗?例如,我可以一行执行此操作吗?example = "example" if "exam" in exam…

为什么使用'=='或'is'比较字符串有时会产生不同的结果? - python

我有一个Python程序,其中将两个变量设置为'public'值。在条件表达式中,我有比较var1 is var2失败,但如果将其更改为var1 == var2,它将返回True。现在,如果我打开Python解释器并进行相同的“是”比较,则此操作成功。>>> s1 = 'public' >>…

在返回'Response'(Python)中传递多个参数 - python

我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…

python JSON对象必须是str,bytes或bytearray,而不是'dict - python

在Python 3中,要加载以前保存的json,如下所示:json.dumps(dictionary)输出是这样的{"('Hello',)": 6, "('Hi',)": 5}当我使用json.loads({"('Hello',)": 6,…

Python exchangelib在子文件夹中读取邮件 - python

我想从Outlook邮箱的子文件夹中读取邮件。Inbox ├──myfolder 我可以使用account.inbox.all()阅读收件箱,但我想阅读myfolder中的邮件我尝试了此页面folder部分中的内容,但无法正确完成https://pypi.python.org/pypi/exchangelib/ 参考方案 您需要首先掌握Folder的myfo…