2016-03-24 3 views
7
my_dict = {'a':[1,2], 'b':[3], 'c':{'d':[4,5], 'e':[6,7]}} 

Мне нужно вывести все комбинации из него, как показано ниже.Сплит-словарь для python для получения всех комбинаций значений

{'a':1, 'b':3, 'c':{'d':4, 'e':6}} 
{'a':1, 'b':3, 'c':{'d':4, 'e':7}} 
{'a':1, 'b':3, 'c':{'d':5, 'e':6}} 
{'a':1, 'b':3, 'c':{'d':5, 'e':7}} 
{'a':2, 'b':3, 'c':{'d':4, 'e':6}} 

и так далее. Там может быть любой уровень вложенности здесь
Пожалуйста, дайте мне знать, как достичь этого
что-то, что я пытался наклеена ниже, но, безусловно, не достигнув нигде

def gen_combinations(data): 
    my_list =[] 
    if isinstance(data, dict): 
     for k, v in data.iteritems(): 
      if isinstance(v, dict): 
       gen_combinations(v) 
      elif isinstance(v, list): 
       for i in range(len(v)): 
        temp_dict = data.copy() 
        temp_dict[k] = v[i] 
        print temp_dict 

my_dict = {'a':[1,2], 'b':[3], 'c':{'d':[4,5], 'e':[6,7]}} 

gen_combinations(my_dict) 

Что привело

{'a': 1, 'c': {'e': [6, 7], 'd': [4, 5]}, 'b': [3]} 
{'a': 2, 'c': {'e': [6, 7], 'd': [4, 5]}, 'b': [3]} 
{'e': 6, 'd': [4, 5]} 
{'e': 7, 'd': [4, 5]} 
{'e': [6, 7], 'd': 4} 
{'e': [6, 7], 'd': 5} 
{'a': [1, 2], 'c': {'e': [6, 7], 'd': [4, 5]}, 'b': 3} 
+1

Пожалуйста, сообщите, что вы пытались до сих пор! –

+0

Предполагаю, что вы хотите сгладить вложенные дикты? –

+0

@Suren Вы можете посмотреть обсуждение под моим ответом? Какой вывод для ключа 'e' вы хотите для' {'a': [1, 2], 'b': [3], 'c': {'d': {4: [3, 4]}, 'e': [6, 7, [1, 2]]}} '? –

ответ

9
from itertools import product 


my_dict = {'a':[1,2], 'b':[3], 'c':{'d':[4,5], 'e':[6,7]}} 


def process(d): 
    to_product = [] # [[('a', 1), ('a', 2)], [('b', 3),], ...] 
    for k, v in d.items(): 
     if isinstance(v, list): 
      to_product.append([(k, i) for i in v]) 
     elif isinstance(v, dict): 
      to_product.append([(k, i) for i in process(v)]) 
     else: 
      to_product.append([(k, v)]) 
    return [dict(l) for l in product(*to_product)] 

for i in process(my_dict): 
    print(i) 

Выход:

{'a': 1, 'b': 3, 'c': {'e': 6, 'd': 4}} 
{'a': 2, 'b': 3, 'c': {'e': 6, 'd': 4}} 
{'a': 1, 'b': 3, 'c': {'e': 6, 'd': 5}} 
{'a': 2, 'b': 3, 'c': {'e': 6, 'd': 5}} 
{'a': 1, 'b': 3, 'c': {'e': 7, 'd': 4}} 
{'a': 2, 'b': 3, 'c': {'e': 7, 'd': 4}} 
{'a': 1, 'b': 3, 'c': {'e': 7, 'd': 5}} 
{'a': 2, 'b': 3, 'c': {'e': 7, 'd': 5}} 

Upd:

код, который работает, как спросил here:

from itertools import product 


my_dict = {'a':[1,2], 'e':[7], 'f':{'x':[{'a':[3,5]}, {'a':[4]}] } } 

def process(d): 
    to_product = [] # [[('a', 1), ('a', 2)], [('b', 3),], ...] 
    for k, v in d.items(): 
     if isinstance(v, list) and all(isinstance(i, dict) for i in v): 
      # specific case, when list of dicts process differently... 
      c = product(*list(process(i) for i in v)) 
      to_product.append([(k, list(l)) for l in c]) 
     elif isinstance(v, list): 
      to_product.append([(k, i) for i in v]) 
     elif isinstance(v, dict): 
      to_product.append([(k, i) for i in process(v)]) 
     else: 
      to_product.append([(k, v)]) 
    return [dict(l) for l in product(*to_product)] 

for i in process(my_dict): 
    print(i) 

Выход:

{'f': {'x': [{'a': 3}, {'a': 4}]}, 'a': 1, 'e': 7} 
{'f': {'x': [{'a': 3}, {'a': 4}]}, 'a': 2, 'e': 7} 
{'f': {'x': [{'a': 5}, {'a': 4}]}, 'a': 1, 'e': 7} 
{'f': {'x': [{'a': 5}, {'a': 4}]}, 'a': 2, 'e': 7} 
+0

Отличный ответ, раньше не знал о функции 'product', очень полезно! –

+0

Ницца! Как разрешить любые другие итерации, кроме как только фильтрации для списка? В строках 'try: to_product.append ([{k: i} для i в v]), за исключением TypeError: ...'? – hochl

+0

Я думаю, что это не сработает для вложенных dicts '{'a': [1, 2], 'b': [3], 'c': {'d': {4: [3, 4]}, 'e ': [6, 7, [1, 2]]}} ' –

-1

Решить его с двумя шагами.

Сначала замените каждый dict на список dicts, сгенерированных gen_combinations, называемый рекурсивно.

Во-вторых, сделайте внутреннее соединение между всеми клавишами. Теперь у каждого ключа есть плоский список.

Смежные вопросы