如何定义一个常数函数
函数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函数获得一个不变的功能?
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
对象的绑定方法。
@ manu-fatto:我不确定自己明白。 'constant_factory'函数只调用一次,就像我的代码只调用一次'itertools.repeat(10)'一样。它返回被反复调用的函数(应该返回相同的值)。我将为它添加一个时间,但它基本上与itertools版本相同,只是在设置代码中有一个额外的函数调用。 – Blckknght 2013-03-08 14:37:43
当然,你是对的... – 2013-03-08 16:17:56
python 3.5的[documentation](https://docs.python.org/3.5/library/collections.html#defaultdict-examples)使用'lambda'。 – Alexey 2016-03-24 08:03:38