私があなたが何を望んでいるかを正しく理解しているなら、以下はそれをするでしょう:
import functools
import operator
L = list('abcd')
def foo(indexable):
return functools.partial(operator.__getitem__, indexable)
g = foo(L)
for i in xrange(len(L)):
print g(i),
アップデート:
私はさらに実験を重ねましたが、少し速い解決策を見つけて驚いていました。これは単にこれに他なりません。
def foo2(indexable):
return indexable.__getitem__
これは、私が一緒に投げた小さなテストベッドを使用して実行すると、次の結果が得られました。
fastest to slowest *_test() function timings:
10,000 elements, 1,000 timeit calls, best of 3
foo2_test() : 1.46 (0.00 times slower)
lambda_test() : 4.15 (1.84 times slower)
foo_test() : 4.28 (1.93 times slower)
使用される各テスト関数は、異なる手法を使用して、タイトループ内のリストの各要素にアクセスするだけです。
これがリンクされた質問に対する並べ替えの回答にどのように適用されるかについて知りたいので、リストの各要素に1回アクセスするだけでなく、リストの並べ替えに使用して、これらの異なる結果を取得しました。
fastest to slowest *_test() function timings:
10,000 elements, 1,000 timeit calls, best of 3
foo2_test() : 13.03 (0.00 times slower)
foo_test() : 14.70 (0.13 times slower)
lambda_test() : 16.25 (0.25 times slower)
どちらの場合も最速でしたがfoo2()
、ソートバージョンではごくわずかでした。
簡単なアクセスの最初の結果セットを取得するために使用される完全なテストベッドのリストは次のとおりです。
import functools
import operator
import timeit
import types
N = 1000
R = 3
SZ = 10000
SUFFIX = '_test'
SUFFIX_LEN = len(SUFFIX)
def setup():
import random
global a_list
a_list = [random.randrange(100) for _ in xrange(SZ)]
def lambda_test():
global a_list
f = lambda i: a_list[i]
for i in xrange(len(a_list)): f(i)
def foo(indexable):
return functools.partial(operator.__getitem__, indexable)
def foo_test():
global a_list
g = foo(a_list)
for i in xrange(len(a_list)): g(i)
def foo2(indexable):
return indexable.__getitem__
def foo2_test():
global a_list
g = foo2(a_list)
for i in xrange(len(a_list)): g(i)
# find all the functions named *SUFFIX in the global namespace
funcs = tuple(value for id,value in globals().items()
if id.endswith(SUFFIX) and type(value) is types.FunctionType)
# run the timing tests and collect results
timings = [(f.func_name[:-SUFFIX_LEN],
min(timeit.repeat(f, setup=setup, repeat=R, number=N))
) for f in funcs]
timings.sort(key=lambda x: x[1]) # sort by speed (ironic use of lambda?)
fastest = timings[0][1] # time fastest one took to run
longest = max(len(t[0]) for t in timings) # len of longest func name (w/o suffix)
print 'fastest to slowest *_test() function timings:\n' \
' {:,d} elements, {:,d} timeit calls, best of {:d}\n'.format(SZ, N, R)
def times_slower(speed, fastest):
return speed/fastest - 1.0
for i in timings:
print "{0:>{width}}{suffix}() : {1:.2f} ({2:.2f} times slower)".format(
i[0], i[1], times_slower(i[1], fastest), width=longest, suffix=SUFFIX)
そして、ソートの使用法をテストするときに異なっていた部分は次のとおりです。
def setup():
import random
global a_list
a_list = [random.randrange(100) for _ in xrange(SZ)]
def lambda_test():
global a_list
sorted(range(len(a_list)), key=lambda i:a_list[i])
def foo(indexable):
return functools.partial(operator.__getitem__, indexable)
def foo_test():
global a_list
sorted(range(len(a_list)), key=foo(a_list))
def foo2(indexable):
return indexable.__getitem__
def foo2_test():
global a_list
sorted(range(len(a_list)), key=foo2(a_list))