web-dev-qa-db-ja.com

辞書の1つのキーに複数の値を追加する

私は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  
118
anon

私があなたの質問を言い換えることができるならば、あなたが望むものはその年に関連した値のリストを含んでいる年とキーのための年と配列を持つ辞書である、そう?これが私のやり方です。

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]
}

一般に、「並列配列」を作成するのはプログラミング方法としてはよくありません。「並列配列」を作成するのは、項目がそれらを含むコンテナーの適切な子ではなく同じインデックスを持つことによって暗黙的に関連付けられるためです。

176
Faisal

あなたは 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]})

これにより、年に関連付けられた数字を見たことがあるかどうかを心配する必要はありません。足りないキーは常にリストになることを知っているので、追加して忘れるだけです。キーがすでに存在する場合は、それが追加されるだけです。

91
jathanism

setdefaultを使用できます。

for line in list:  
    d.setdefault(year, []).append(value)

これは、setdefaultがリストを辞書に設定するとともにリストを返すため、およびリストが可変であるため、setdefaultによって返されるバージョンに追加することは、辞書自体のバージョンに追加することと同じであるためです。それが理にかなっている場合。

38
Daniel Roseman
d = {} 

# import list of year,value pairs

for year,value in mylist:
    try:
        d[year].append(value)
    except KeyError:
        d[year] = [value]

Pythonの方法 - 許可を求めるよりも許しを受ける方が簡単です。

17
Hugh Bothwell

これは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)
10
USER_1

これらの値をタプルのリストに入れる方が簡単です。これを行うには、リストスライスと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はキーとデフォルト値を取り、関連付けられた値、または現在の値がない場合はデフォルト値を返します。この場合、空のリストまたは移入されたリストのいずれかを取得し、それに現在の値を追加します。

4
erik

(ほぼ)ワンライナーが必要な場合:

コレクションからのインポート.deque 
 
 d = {} 
 deque((d.setdefault(year、[])。yearのためのappend(value)、value in source_of_data)、maxlen = 0)

dict.setdefaultを使用すると、「キーが既に存在するかどうかを確認し、存在しない場合は新しいリストを作成する」という概念を1つの呼び出しにまとめることができます。これにより、キューの長さがゼロに設定されるため、dequeができるだけ効率的に消費するジェネレータ式を記述できます。両端キューはすぐに破棄され、結果はdになります。

これは私がちょうど楽しみのためにしたことです。使用はお勧めしません。両端キューを使って任意のイテラブルを消費する時間と場所がありますが、これは間違いではありません。

2
Mad Physicist