web-dev-qa-db-ja.com

Python辞書でリストを保存および更新する:なぜこれが起こるのですか?

次のようなデータのリストがあります。

// timestep,x_position,y_position
0,4,7
0,2,7
0,9,5
0,6,7
1,2,5
1,4,7
1,9,0
1,6,8

...そして、私はこれを次のように見せたいです:

0, (4,7), (2,7), (9,5), (6,7)
1, (2,5), (4,7), (9,0), (6.8)

私の計画は、tの値が辞書のキーであり、キーに対する値がリストになるような辞書を使用することでした。次に、各(x、y)をリストに追加できます。何かのようなもの:

# where t = 0, c = (4,7), d = {}

# code 1
d[t].append(c)

これにより、IDLEが失敗します。ただし、次の場合:

# code 2
d[t] = []
d[t].append(c)

...これは動作します。

質問は次のとおりです。なぜコード2は機能するのに、コード1は機能しないのでしょうか。

PS私がやろうとしていることを改善することは非常に興味深いことです!!入力をループするたびに辞書をチェックして、辞書キーが既に存在するかどうかを確認する必要があると思います。max(d.keys())のようなものを使用して推測します。辞書の値として空のリストを作成し、次のループスルーにデータを追加します。

27
user41121

見てみましょう

_d[t].append(c)
_

_d[t]_の値は何ですか?それを試してみてください。

_d = {}
t = 0
d[t]
_

あなたは何を得ますか?ああ。 dにはtのキーを持つものは何もありません。

これを試してみてください。

_d[t] = []
d[t]
_

ああ。これで、dにキーがtの何かがあります。

できることはいくつかあります。

  1. 例2を使用します。
  2. setdefaultを使用します。 d.setdefault(t,[]).append(c)
  3. collections.defaultdict を使用します。単純な辞書_{}_の代わりにdefaultdict(list)を使用します。

編集1.最適化

上記の形式のファイルからの入力行:ts、x、yが与えられた場合、グループ化プロセスは不要です。 (ts、x、y)の単純なリストから(ts、(x、y)、(x、y)、(x、y)、...)のより複雑なリストに進む理由はありません。元のリストは、到着したとおりに処理できます。

_d= collections.defaultdict(list)
for ts, x, y in someFileOrListOrQueryOrWhatever:
    d[ts].append( (x,y) )
_

編集2.質問に答える

「辞書を初期化するとき、キーと値のデータ構造がどのようになるかを辞書に伝える必要がありますか?」

質問の意味がわかりません。すべての辞書がキーと値の構造であるため、質問はあまり明確ではありません。そこで、質問に答える可能性のある3つの選択肢を検討します。

例2

初期化

_d= {}
_

使用する

_if t not in d:
    d[t] = list()
d[t].append( c )
_

各辞書値は、何らかの有用な構造に初期化する必要があります。この場合、キーが存在するかどうかを確認します。キーが欠落している場合、キーを作成して空のリストを割り当てます。

デフォルト設定

初期化

_d= {}
_

使用する

_d.setdefault(t,list()).append( c )
_

この場合、setdefaultメソッドを利用して、キーに関連付けられた値を取得するか、欠落しているキーに関連付けられた新しい値を作成します。

default dict

初期化

_import collections
d = collections.defaultdict(list)
_

使用する

_d[t].append( c )
_

defaultdictは、欠落しているキーに初期化関数を使用します。この場合、list関数を提供して、不足しているキーに対して新しい空のリストが作成されるようにします。

72
S.Lott

Setdefaultを使用したいと思います。使用するのは少し奇妙ですが、必要なことを正確に行います。

d.setdefault(t, []).append(c)

.setdefaultメソッドは、キーが存在する場合、辞書のキーtにバインドされている要素(この場合はリスト)を返します。そうでない場合は、空のリストをキーtにバインドして返します。どちらにしても、リストはそこにあり、.appendメソッドは、タプルcを追加できます。

12
Tim Pietzcker
dict=[]  //it's not a dict, it's a list, the dictionary is dict={}
elem=[1,2,3]
dict.append(elem)

この方法で単一の要素にアクセスできます。

print dict[0] // 0 is the index

出力は次のようになります。

[1, 2, 3]
1
Giancarlo

データが目的の基準でまだソートされていない場合、データをグループ化するのに役立つコードを次に示します。

#!/usr/bin/env python
"""
$ cat data_shuffled.txt
0,2,7
1,4,7
0,4,7
1,9,0
1,2,5
0,6,7
1,6,8
0,9,5
"""
from itertools   import groupby
from operator    import itemgetter

# load the data and make sure it is sorted by the first column
sortby_key = itemgetter(0)
data = sorted((map(int, line.split(',')) for line in open('data_shuffled.txt')),
              key=sortby_key)

# group by the first column
grouped_data = []
for key, group in groupby(data, key=sortby_key):
    assert key == len(grouped_data) # assume the first column is 0,1, ...
    grouped_data.append([trio[1:] for trio in group])

# print the data
for i, pairs in enumerate(grouped_data):
    print i, pairs

出力:

0 [[2, 7], [4, 7], [6, 7], [9, 5]]
1 [[4, 7], [9, 0], [2, 5], [6, 8]]
1
jfs