如何定义一个常数函数

3

我在文档中发现:

函数int()总是返回零,它只是常数函数的特例。创建常数函数更快、更灵活的方法是使用itertools.repeat(),它可以提供任何常数值(不仅仅是零):

def constant_factory(value): 
   return itertools.repeat(value).next

d = defaultdict(constant_factory('<missing>'))
d.update(name='John', action='ran')
'%(name)s %(action)s to %(object)s' % d 

'John ran to <missing>'

为什么不使用lambda函数来获取常数函数?

Python 3.5的文档使用了lambda - Alexey
1个回答

3
< p > itertools.repeat 类是用 C 编写的,比使用 Python 编写的函数稍微快一些。以下是我使用 timeit 模块对不同常量值函数实现进行的测试:

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17)
[MSC v.1600 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import timeit
>>> import itertools
>>> itertools_version = itertools.repeat(10).__next__
>>> lambda_version = lambda:10
>>> def function_version():
    return 10
>>> def constant_factory(n):
    return itertools.repeat(n).__next__
>>> factory_version = constant_factory(10)
>>> timeit.timeit("for i in range(100): f()",
                  setup="from __main__ import itertools_version as f")
7.115707915662512
>>> timeit.timeit("for i in range(100): f()",
                  setup="from __main__ import lambda_version as f")
11.479014911317307
>>> timeit.timeit("for i in range(100): f()",
                  setup="from __main__ import function_version as f")
11.561433023257619
>>> timeit.timeit("for i in range(100): f()",
                  setup="from __main__ import factory_version as f")
7.166709032038568

然而,如果这种性能提升对您的情况不是至关重要的话,请仔细考虑一下。如果这不是关键性能代码,则在以后阅读时使用您认为最容易理解的实现即可。
如果您只会使用常量函数一次,我认为lambda函数完全适合。如果您经常使用它,则命名函数可能更好。如果它被调用在您最敏感的逻辑的内部循环中,则使用一个itertools.repeat对象的bound方法。

@manu-fatto:我不确定我理解了。constant_factory函数只被调用一次,就像我的代码只调用itertools.repeat(10)一次一样。它返回被反复调用的函数(应该返回相同的值)。我会为它添加一个计时器,但它本质上与itertools版本相同,只是在设置代码中多了一个额外的函数调用。 - Blckknght
@EmanuelePaolini如果这个回答有帮助到您,请确保“接受”它。 - StardustGogeta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接