2017-08-30 7 views
0

文字列に関連付けられた配列(同じ長さ)の辞書があります。私の目標は、同じキーで新しい辞書を作成することですが、必要な要素だけを残して配列を切断します。私はそれを行う関数を書いたが、問題は、すべてのキーに関連付けられた同じ配列(正しい長さの長さ)を持つ辞書を返すということです。ここでは機能があります:最終print dic_extrは、すべてのキーに関連付けられている同じ配列を持つ辞書を示しているpython:辞書とnumpy.arrayの問題

def extract_years(dic,initial_year,final_year): 

    dic_extr = {} 
    l = numpy.size(dic[dic.keys()[0]]) 

    if final_year != 2013 : 
     a = numpy.zeros((final_year - initial_year)*251) 
    elif final_year == 2013 : 
     a = numpy.zeros(l - (initial_year-1998)*251) 

    for i in range(0,len(dic)): 
     #print i 
     for k in range (0,numpy.size(a)): 
      a[k] = dic[dic.keys()[i]][(initial_year-1998)*251 + k]   
      #print k 

     dic_extr[dic.keys()[i]] = a 
     print dic.keys()[i] 
     print dic_extr[dic.keys()[i]] 


    print dic_extr.keys() 
    print dic_extr 
    return dic_extr 

私が言ったように、print dic_extr[dic.keys()[i]]は正しい結果を示しています。

+0

インデントを修正してください。 – zipa

+0

予期せぬ結果を持つ関数呼び出しの例と、期待していた結果を挙げることができますか? – GLR

+0

https://pastebin.com/GSncW5DE ディクショナリの要素数が300を超え、アレイの長さが非常に長いため、ここに端末出力を貼り付けました。最初のプリントは、 'print dic.keys()[i] です。print dic_extr [dic.keys()[i]]' 最後は 'print dic_extr'ですが全く違っています。新しい辞書 – tidus

答えて

2

Pythonでは、すべてのオブジェクトはポインタです。したがって、外側のforループの繰り返しごとにaの新しいインスタンスを作成する必要があります。

def extract_years(dic,initial_year,final_year): 

    dic_extr = {} 
    l = numpy.size(dic[dic.keys()[0]]) 

    for i in range(0,len(dic)): 

     if final_year != 2013 : 
      a = numpy.zeros((final_year - initial_year)*251) 
     elif final_year == 2013 : 
      a = numpy.zeros(l - (initial_year-1998)*251) 

     for k in range (0,numpy.size(a)): 
      a[k] = dic[dic.keys()[i]][(initial_year-1998)*251 + k]   
      #print k 

     dic_extr[dic.keys()[i]] = a 
     print dic.keys()[i] 
     print dic_extr[dic.keys()[i]] 


    print dic_extr.keys() 
    print dic_extr 
    return dic_extr 

おそらくこれが最もエレガントな解決策ではありませんが、私はそれが動作するはずだと思う:あなたはこのように、そのループの内側にa配列を初期化する、例えば、これを行うことができます。

+0

の中で一番最初に全体が印刷されることが期待されていました。 – tidus

+0

答えを有効とマークしてください。 – GLR

0

私はあなたが変数を定義するための可変性とニシキヘビの方法の典型的な問題に遭遇したと思う:あなたはnumpy.zeros()を使用することにより、可変タイプであることをaを定義

  1. 次に、aに特定の値を設定しますが、実際にはポインタのリストへのポインタがあり、実際の値を指しています。
  2. dic_extr[dic.keys()[i]] = aを使用すると、ポインターの一覧ではなく、dic_extrの配列にこのポインターをコピーします。
  3. 次に、ポインタリストが参照するオブジェクトを変更します。
  4. dic_extr[dic.keys()[i]] = aを使用すると、dic_extr配列へのポインタのリストへのポインタをコピーします。ポインタリスト自体はコピーしません。

最後に両方のポインタが同じポインタリストを指しています。簡単な例:

a = [1, 2, 3, 4, 5] 
b = a 
b[0] = 10 
print(a) # returns [10, 2, 3, 4, 5] 

あなたが実際のコピーを作成するdic_extr[dic.keys()[i]] = a[:]を使用することができます。

Here is also a nice explaination to mutability in python.

+0

この単純な変更は機能しませんでした – tidus

+0

それでも同じことを指していますか、または何が問題なのですか? –

+0

同じ出力 – tidus