1

この問題を解決するために数行のコードを書きましたが、プロファイラーは非常に時間がかかると言っています。(kernprof 行ごとのプロファイラーを使用) コードは次のとおりです。

comp = [1, 2, 3] #comp is list with always 3 elements, values 1, 2, 3 are just for illustration
m = max(comp)
max_where = [i for i, j in enumerate(comp) if j == m]
if 0 in max_where: 
    some action1
if 1 in max_where: 
    some action2
if 2 in max_where: 
    some action3

プロファイラーによると、max_where の計算にほとんどの時間が費やされています。不必要な操作を避けるために、この計算を if-tree に分割しようとしましたが、結果は満足のいくものではありませんでした。

お願いします、私はそれを間違っていますか、それともただのpythonですか?

4

5 に答える 5

3

常に 3 つの要素である場合は、単純に次のようにしないでください。

comp = [1, 2, 3] 
m = max(comp)

if comp[0] == m: 
    some action
if comp[1] == m: 
    some action
if comp[2] == m: 
    some action
于 2013-02-01T12:17:07.183 に答える
3

これを何度も行っていて、すべてのリストを同時に利用できる場合は、を使用してすべてのリストのnumpy.argmaxインデックスを取得できます。

于 2013-02-01T12:20:45.650 に答える
2

これは時間のかかる操作だとおっしゃっていますが、これが実際にプログラムに影響を与えるとは思えません。コードの実行が遅いため、これが問題を引き起こしていることに実際に気付きましたか? そうでない場合は、最適化する意味がありません。

これは、私が考えることができる小さな最適化があると言いました-それは、理解でsetはなくを使用することです。これにより、3 つのメンバーシップ テストが高速化されます。listmax_where

max_where = {i for i, j in enumerate(comp) if j == m}

とはいえ、アイテム/チェックが3つしかないため、セットの構築には節約するよりも時間がかかる可能性があります.

一般に、3 つのアイテムのリストでは、この操作にかかる時間はごくわずかです。私のシステムでは、この操作を実行するのに0.5 マイクロ秒かかります。

要するに:気にしないでください。これが、高速化が必要なプログラムのボトルネックであることが証明されていない限り、現在のコードで問題ありません。

于 2013-02-01T12:15:03.233 に答える
1

これはどう:

sample = [3,1,2]    
dic = {0:func_a,1:func_b,2:func_c}
x = max(sample) 
y = sample.index(x)
dic[y]

前述のように、そして当然のことながら反対票を投じた場合、これは複数の関数呼び出しでは機能しません。ただし、これは次のようになります。

sample = [3,1,3]    
dic = {0:"func_a",1:"func_b",2:"func_c"}
max_val = max(sample) 
max_indices = [index for index, elem in enumerate(sample) if elem==max_val]
for key in max_indices:
    dic[key]

これは、上記の他のソリューションと非常によく似ています。しばらく経ちましたが、それは正しくありませんでした。:)

乾杯!

于 2013-02-01T16:01:06.757 に答える
1

forループを使用して、Tobias の回答を拡張します。

comp = [1, 2, 3] 
m = max(comp)

for index in range(len(comp)):
    if comp[index] == m:
        # some action

インデックスは0から始まるので、する必要はありませlen(comp) + 1。実際の要素ではなく、ループ内でインデックスを使用することを好みforます。かなり高速になるからです。プロセス中に、特定の要素のインデックスが必要になる場合があります。次に、使用l.index(obj)は時間を無駄にします (ほんのわずかな量であっても --- 長いプロセスの場合、これは面倒になります)。

これは、すべてのプロセス ( の) が非常に似ていることも前提としていcomp[index]ます。同じプロセスですが、変数が異なります。インデックスごとに大幅に異なるプロセスがある場合、これは機能しません。

ただし、 を使用すると、すでにインデックスがあり、 (ループによって与えられるインデックスと共に)for index in range(len(l)):アイテムに簡単にアクセスできます。l[index]

奇妙なことに、Tobias の実装の方が速いようです (私はそうではないと思いました)。

comp = [1, 2, 3]
m = max(comp)
from timeit import timeit
def test1():
    if comp[0] == m: return m
    if comp[1] == m: return m
    if comp[2] == m: return m

def test2():
    for index in range(len(comp)):
        if comp[index] == m: return m

print 'test1:', timeit(test1, number = 1000)
print 'test2:', timeit(test2, number = 1000)

戻り値:

test1: 0.00121262329299
test2: 0.00469034990534

私の実装は、長いリストの方が高速かもしれません (確かではありません)。ただし、そのためのコードを書くのは面倒です (繰り返しを使用する長いリストの場合if comp[n] == m)。

于 2013-02-01T13:25:21.167 に答える