2013-11-13 2 views
0

Итак, у меня есть два словаря.Картошский продукт для двух словарей python

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 
+0

Ваш первый два уплощение 'li' заархивированы с собой, ваш второй два конкатенации 3 экземпляра' li'. Какой ты хочешь? – roippi

+0

Как вы получаете три копии «онлайн»? Вы пытаетесь получить копию каждого 'статуса' для каждого члена' zip (здорового, безумного) ', копии каждого' Absent' для каждого члена 'zip (здорового, безумного)', копии каждого ' здоровый' для каждого члена 'zip (status, Absent)' и копия каждого 'insane' для каждого члена' zip (status, Absent) '? – abarnert

+0

Пожалуйста, объясните свой декартовый продукт, ваш ожидаемый результат не так очевиден. –

ответ

5

Лучшее предположение, основанное на интерпретации @ abarnert (и предполагая, что healthy и insane значения в выходной ток не правы, поскольку у них есть только четыре члена):

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') 
+0

Хороший перевод на Python. Это так же беспорядок на Python, как и на английском языке, но это не ваша ошибка ... – abarnert

+0

Неясно, каков ожидаемый результат, если 'd1.viewkeys() & d2.viewkeys()' не пуст, т. Е. Если есть общие ключи. – jfs

+0

@ J.F.Sebastian: хорошая точка. Вышеизложенное будет иметь смысл, если они не пересекаются. – DSM

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 
1

что мне нужно, это что первый словарь повторить первое значение количество раз значений в второй словарь

ОК, поэтому вы хотите вывести каждое значение в первом словаре с помощью zip значений во втором словаре и наоборот.

Для этого вам нужно будет разархивировать значения двух словарей, произвести результат, разархивировать, закрепить каждую половину получаемого 2-кортежа ключами из соответствующего исходного словаря, сгладить два результирующих итератора пары ключ-значение в один и сделать из него словарь. (Вместо этого вы можете сгладить значения и закрепить их с помощью сплющенных ключей от двух диктонов, но я не уверен, что гарантирует правильный порядок ...)

Это звучит как большой беспорядок, но это то, что вы просите для.

4

попробуйте это: он объединяет два значения 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)} 
+0

Хех. Я предполагаю, что есть один очевидный способ сделать это, даже в тех случаях, когда то, что «оно» не совсем очевидно. : ^) – DSM

+0

да, мы, похоже, пришли в то же место! это довольно интересно, почти линия для линии то же самое, кроме конструкции dict. не копируй, я клянусь! :) – Garth5689

3

Я столкнулся с этой проблемой некоторое время назад, создавая тестовые примеры. У меня есть пакет на pip, который теперь называется «looper», который расширяет itertools с помощью некоторой магии словаря и других вещей, которые я нашел полезными.

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

То, что вы хотите, кажется, не быть полным декартово произведение двух dictionarys, который будет долго 36 пунктов, комбинируя каждую клавишу d1 [k1] * d1 [k2] * d2 [k1 ] * d2 [k2].

Вместо этого вы, похоже, хотите, чтобы 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'} 
Смежные вопросы