3

私が見つけたドキュメントで

常にゼロを返す関数 int() は、定数関数の特殊なケースです。定数関数を作成するより高速で柔軟な方法は、任意の定数値 (0 だけでなく) を提供できる 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>'

単純にラムダ関数を使用して定数関数を取得しないのはなぜですか?

4

1 に答える 1

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

ただし、この適度なパフォーマンスの向上が状況にとって価値があるかどうかを慎重に検討してください。これがパフォーマンス クリティカルなコードでない場合は、後で読むときに最も理解しやすいと思われる実装を使用する必要があります。

定数関数を 1 回だけ使用する場合は、ラムダが最適だと思います。頻繁に使用するものであれば、名前付き関数の方がよいでしょう。最も時間に敏感なロジックの内部ループで呼び出されている場合は、itertools.repeatオブジェクトのバインドされたメソッドを使用します。

于 2013-03-08T11:38:45.457 に答える