私はpythonが初めてなので、年のリストと年ごとの値を持っています。私がしたいのは、その年がすでに辞書に存在するかどうかを確認し、存在する場合は特定のキーの値のリストに値を追加することです。
たとえば、年のリストがあり、年ごとに1つの値があります。
2010
2
2009
4
1989
8
2009
7
私がやりたいのは、年をキーとして、そしてそれらの1桁の数字を値として持つ辞書を作成することです。ただし、2009年に2回リストした場合は、その2番目の値をその辞書内の値のリストに追加したいので、次のようにします。
2010: 2
2009: 4, 7
1989: 8
今、私は以下の通りです:
d = dict()
years = []
(get 2 column list of years and values)
for line in list:
year = line[0]
value = line[1]
for line in list:
if year in d.keys():
d[value].append(value)
else:
d[value] = value
d[year] = year
私があなたの質問を言い換えることができるならば、あなたが望むものはその年に関連した値のリストを含んでいる年とキーのための年と配列を持つ辞書である、そう?これが私のやり方です。
years_dict = dict()
for line in list:
if line[0] in years_dict:
# append the new number to the existing array at this slot
years_dict[line[0]].append(line[1])
else:
# create a new array in this slot
years_dict[line[0]] = [line[1]]
Years_dictで終わることになるのは、次のような辞書です。
{
"2010": [2],
"2009": [4,7],
"1989": [8]
}
一般に、「並列配列」を作成するのはプログラミング方法としてはよくありません。「並列配列」を作成するのは、項目がそれらを含むコンテナーの適切な子ではなく同じインデックスを持つことによって暗黙的に関連付けられるためです。
あなたは collections.defaultdict
(Python 2.5で追加された)を使うのが一番良いでしょう。これにより、欠けているキーのデフォルトのオブジェクトタイプ(list
など)を指定できます。
そのため、最初にキーが存在しない場合にキーを作成してからキーの値に追加するのではなく、仲介者を切り取り、存在しないキーに直接追加して目的の結果を得ます。
あなたのデータを使った簡単な例:
>>> from collections import defaultdict
>>> data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)]
>>> d = defaultdict(list)
>>> d
defaultdict(<type 'list'>, {})
>>> for year, month in data:
... d[year].append(month)
...
>>> d
defaultdict(<type 'list'>, {2009: [4, 7], 2010: [2], 1989: [8]})
これにより、年に関連付けられた数字を見たことがあるかどうかを心配する必要はありません。足りないキーは常にリストになることを知っているので、追加して忘れるだけです。キーがすでに存在する場合は、それが追加されるだけです。
setdefault
を使用できます。
for line in list:
d.setdefault(year, []).append(value)
これは、setdefaultがリストを辞書に設定するとともにリストを返すため、およびリストが可変であるため、setdefaultによって返されるバージョンに追加することは、辞書自体のバージョンに追加することと同じであるためです。それが理にかなっている場合。
d = {}
# import list of year,value pairs
for year,value in mylist:
try:
d[year].append(value)
except KeyError:
d[year] = [value]
Pythonの方法 - 許可を求めるよりも許しを受ける方が簡単です。
これはnot in
演算子を使用してこれを行うための代替方法です。
# define an empty dict
years_dict = dict()
for line in list:
# here define what key is, for example,
key = line[0]
# check if key is already present in dict
if key not in years_dict:
years_dict[key] = []
# append some value
years_dict[key].append(some.value)
これらの値をタプルのリストに入れる方が簡単です。これを行うには、リストスライスとZip機能を使用できます。
data_in = [2010,2,2009,4,1989,8,2009,7]
data_pairs = Zip(data_in[::2],data_in[1::2])
Zipは任意の数のリスト、この場合はdata_in
の偶数エントリと奇数エントリを取り、それらを1つのTupleにまとめます。
これでsetdefault
メソッドを使うことができます。
data_dict = {}
for x in data_pairs:
data_dict.setdefault(x[0],[]).append(x[1])
setdefault
はキーとデフォルト値を取り、関連付けられた値、または現在の値がない場合はデフォルト値を返します。この場合、空のリストまたは移入されたリストのいずれかを取得し、それに現在の値を追加します。
(ほぼ)ワンライナーが必要な場合:
コレクションからのインポート.deque d = {} deque((d.setdefault(year、[])。yearのためのappend(value)、value in source_of_data)、maxlen = 0)
dict.setdefault
を使用すると、「キーが既に存在するかどうかを確認し、存在しない場合は新しいリストを作成する」という概念を1つの呼び出しにまとめることができます。これにより、キューの長さがゼロに設定されるため、deque
ができるだけ効率的に消費するジェネレータ式を記述できます。両端キューはすぐに破棄され、結果はd
になります。
これは私がちょうど楽しみのためにしたことです。使用はお勧めしません。両端キューを使って任意のイテラブルを消費する時間と場所がありますが、これは間違いではありません。