0

さて、私は2つの辞書を持っています。

dictionary_1 = {'status': ['online', 'Away', 'Offline'],
                'Absent':['yes', 'no', 'half day']}
dictionary_2 = {'healthy': ['yes', 'no'],
                'insane': ['yes', 'no']

今、私はそれらを組み合わせて、新しい辞書を取得する必要があります:

{'status': ['online', 'online', 'away', 'away', 'Offline', 'Offline'],
 'Absent': ['yes', 'yes', 'no', 'no', 'half day', 'half day'],
 'healthy': ['yes', 'no', 'yes', 'no', 'yes', 'no'],
 'insane': ['yes', 'no', 'yes', 'no', 'yes', 'no']
}

これは非常に遅い更新ですが、誰かが興味を持っている場合は itertools なしでそれを行う方法を見つけました。

def cartesian_product(dict1, dict2):
    cartesian_dict = {}
    dict1_length = len(list(dict1.values())[0])
    dict2_length = len(list(dict2.values())[0])
    h = []
    for key in dict1:
        for value in dict1[key]:
            if not key in cartesian_dict:
                cartesian_dict[key] = []
                cartesian_dict[key].extend([value]*dict2_length)
            else:   
                cartesian_dict[key].extend([value]*dict2_length)
    for key in dict2:
        cartesian_dict[key] = dict2[key]*dict1_length
    return cartesian_dict
4

5 に答える 5

5

@abarnert の解釈に基づく最良の推測 (および、現在の出力の と の値が間違っていると仮定すると、healthyメンバーinsaneは 4 つしかないため):

d1 = {'status': ['online', 'Away', 'Offline'] ,'absent':['yes', 'no', 'half day']}
d2 = {'healthy': ['yes', 'no'], 'insane': ['yes', 'no']}
d1_columns = zip(*d1.values())
d2_columns = zip(*d2.values())
col_groups = [c1+c2 for c1, c2 in itertools.product(d1_columns, d2_columns)]
rows = zip(*col_groups)
combined_keys = list(d1) + list(d2)
d_combined = dict(zip(combined_keys, rows))

生産する

>>> pprint.pprint(d_combined)
{'absent': ('yes', 'yes', 'no', 'no', 'half day', 'half day'),
 'healthy': ('yes', 'no', 'yes', 'no', 'yes', 'no'),
 'insane': ('yes', 'no', 'yes', 'no', 'yes', 'no'),
 'status': ('online', 'online', 'Away', 'Away', 'Offline', 'Offline')}

または、ご注文で、

>>> order = ["status", "absent", "healthy", "insane"]
>>> for k in order:
    print k, d_combined[k]
...     
status ('online', 'online', 'Away', 'Away', 'Offline', 'Offline')
absent ('yes', 'yes', 'no', 'no', 'half day', 'half day')
healthy ('yes', 'no', 'yes', 'no', 'yes', 'no')
insane ('yes', 'no', 'yes', 'no', 'yes', 'no')
于 2013-11-13T20:10:33.637 に答える
4

これを試してください: 2 つの dict 値を結合し、積を計算してから、それらを再度分離して dict に変換します。

import itertools

dictionary_1 = {'status': ['online', 'Away', 'Offline'],
                'Absent':['yes', 'no', 'half day']}
dictionary_2 = {'healthy': ['yes', 'no', 'recovering'],
                'insane': ['yes', 'no', 'partially' ]}

keys = dictionary_1.keys() + dictionary_2.keys()

first_values = zip(*dictionary_1.values())
# [('online','yes'), ('Away','no'),('Offline','half day')]

second_values = zip(*dictionary_2.values())

# this product will replicate the first_values 
# as many times as second_values exists
values_list = [i1+i2 for(i1,i2) in itertools.product(first_values,second_values)]

#re-separate the value lists for dict.
values = zip(*values_list)

new_dict = {key:list(values[i]) for i,key in enumerate(keys)}  
于 2013-11-13T20:11:07.883 に答える
3

テストケースを作成する前に、この問題に遭遇しました。私は 'looper' と呼ばれる pip のパッケージを持っています。

https://pypi.python.org/pypi/looper

あなたが望むのは、各キー d1[k1] * d1[k2] * d2[k1] * d2[k2] を組み合わせた 36 項目の長さになる 2 つの辞書の完全なデカルト積ではないようです。

代わりに、d1[k1,k2] * d2[k1,k2] が必要なようで、キーごとに n を均等に繰り返します。これは zip 関数として知られており、dict_zip は辞書に対してこれを行います。

from pprint import pprint
from looper import iterutil

dict_1 = {'status':  ['online', 'Away', 'Offline'],
          'Absent':  ['yes', 'no', 'half day']}
dict_2 = {'healthy': ['yes', 'no'],
          'insane':  ['yes', 'no']}

# the first thing to do is to zip the dictionaries up. This produces a dictionary for each value of n in d[k][n]
zipped_dict_1 = iterutil.dict_zip(**dict_1)
# {'Absent': 'yes', 'status': 'online'}
# {'Absent': 'no', 'status': 'Away'}
# {'Absent': 'half day', 'status': 'Offline'}
zipped_dict_2 = iterutil.dict_zip(**dict_2)
# {'healthy': 'yes', 'insane': 'yes'}
# {'healthy': 'no', 'insane': 'no'}


# Now the output is a list of flattened dictionaries, take the Cartesian product of them.
product_dict = iterutil.product(zipped_dict_1,zipped_dict_2) 
# ({'Absent': 'yes', 'status': 'online'}, {'healthy': 'yes', 'insane': 'yes'})
# ({'Absent': 'yes', 'status': 'online'}, {'healthy': 'no', 'insane': 'no'})
# ({'Absent': 'no', 'status': 'Away'}, {'healthy': 'yes', 'insane': 'yes'})
# ({'Absent': 'no', 'status': 'Away'}, {'healthy': 'no', 'insane': 'no'})
# ({'Absent': 'half day', 'status': 'Offline'}, {'healthy': 'yes', 'insane': 'yes'})
# ({'Absent': 'half day', 'status': 'Offline'}, {'healthy': 'no', 'insane': 'no'})

# The product function produces tuples which must be combined in to a final dictionary.
# Merge the dictionaries using imap
merged_dict =  iterutil.imap(lambda x: dict(x[0].items()+x[1].items()),product_dict)

for d in merged_dict:
    pprint(d)

出力

{'Absent': 'yes', 'healthy': 'yes', 'insane': 'yes', 'status': 'online'}
{'Absent': 'yes', 'healthy': 'no', 'insane': 'no', 'status': 'online'}
{'Absent': 'no', 'healthy': 'yes', 'insane': 'yes', 'status': 'Away'}
{'Absent': 'no', 'healthy': 'no', 'insane': 'no', 'status': 'Away'}
{'Absent': 'half day', 'healthy': 'yes', 'insane': 'yes', 'status': 'Offline'}
{'Absent': 'half day', 'healthy': 'no', 'insane': 'no', 'status': 'Offline'}
于 2014-04-03T17:01:48.677 に答える
0

辞書を配列に入れてから、次のようにします。

dictionaries[dict_1,dict_2]

product = {}
arr = []
for d in dictionaries:
    for k in dictionaries[d]:
        arr.append(d.get(k))
        product[k] = None
for k in product:
    product[k] = arr
于 2013-11-13T19:48:11.977 に答える