2013-03-08 111 views
3

documentation我發現如何定義一個常數函數

函數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函數獲得一個不變的功能?

+0

python 3.5的[documentation](https://docs.python.org/3.5/library/collections.html#defaultdict-examples)使用'lambda'。 – Alexey 2016-03-24 08:03:38

回答

3

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對象的綁定方法。

+0

@ manu-fatto:我不確定自己明白。 'constant_factory'函數只調用一次,就像我的代碼只調用一次'itertools.repeat(10)'一樣。它返回被反覆調用的函數(應該返回相同的值)。我將爲它添加一個時間,但它基本上與itertools版本相同,只是在設置代碼中有一個額外的函數調用。 – Blckknght 2013-03-08 14:37:43

+0

當然,你是對的... – 2013-03-08 16:17:56

相關問題