2009-03-17 7 views
10

最初はPythonを初めて使ったので、何か見落としてしまったことをお詫びしますが、dict.fromkeys(または類似のもの)を使用して別のリストのキーが提供されるリストの辞書を作成したいと考えています。私はいくつかのタイミングテストを実行することだし、キーを入力変数と実行のための時間を格納するためのリストであるために私が欲しい:dict.fromkeysを使用して各キーに一意の値を作成する方法を教えてください。

def benchmark(input): 
    ... 
    return time_taken 

runs = 10 
inputs = (1, 2, 3, 5, 8, 13, 21, 34, 55) 
results = dict.fromkeys(inputs, []) 

for run in range(0, runs): 
    for i in inputs: 
     results[i].append(benchmark(i)) 

私がいる問題は、すべてのキーであることです辞書は同じリストを共有するように見え、各実行は単にそれに追加されます。 fromkeysを使用して、各キーに固有の空のリストを生成する方法はありますか?そうでない場合は、手作業で結果の辞書を生成せずにこれを行う別の方法がありますか?

答えて

10

問題が

results = dict.fromkeys(inputs, []) 

[]

で右が、一度だけ評価されていることです。

私はそのようにこのコードを書き直したい:

runs = 10 
inputs = (1, 2, 3, 5, 8, 13, 21, 34, 55) 
results = {} 

for run in range(runs): 
    for i in inputs: 
     results.setdefault(i,[]).append(benchmark(i)) 

その他のオプションは次のとおりです。

runs = 10 
inputs = (1, 2, 3, 5, 8, 13, 21, 34, 55) 
results = dict([(i,[]) for i in inputs]) 

for run in range(runs): 
    for i in inputs: 
     results[i].append(benchmark(i)) 
+0

すごくうまくいく!ありがとう! (私はそれらを使用しなければならなかった前に空のリストを生成することができたらいいと思うが) –

+0

それは不可能である。 []またはlist()を呼び出すと、オブジェクトが作成され、変数にバインドされます。たとえば、このx = [[]] * 10を調べてください。 x [0] .append( 'test'); print x – vartec

+0

OK、そこにはすべてのリストがインスタンス化された代替案があります。 – vartec

12

defaultdict(Python 2.5以降が必要です)をご覧ください。

from collections import defaultdict 

def benchmark(input): 
    ... 
    return time_taken 

runs = 10 
inputs = (1, 2, 3, 5, 8, 13, 21, 34, 55) 
results = defaultdict(list) # Creates a dict where the default value for any key is an empty list 

for run in range(0, runs): 
    for i in inputs: 
     results[i].append(benchmark(i)) 
+0

これはうまくいきます。私は、それが "真の"辞書であり、1つの偽装のクラスではないことを望みます。 –

+0

公正であるためには、それは非常に最小限の変更を加えたサブクラスなので、「1になりすます」ことはやや強いようです。 –

+0

+1 Python <2.5でコードを使用する必要がないと確信しているなら、それを行う方法です。 (最近私はホスティングの提供を見てきましたが、まだPython 2.4を使用しています)。 – vartec

2

あなたが新しい何かを学ぶためにしたくない場合にも、これを行うことができます(私はお勧めしますが、あなたは何をしますか?)私はどの方法がより速いのか不思議です。

results = dict.fromkeys(inputs) 

for run in range(0, runs): 
    for i in inputs: 
     if not results[i]: 
      results[i] = [] 
     results[i].append(benchmark(i)) 
関連する問題