У меня есть такой словарь:
d = {'o1': [1, 2, 3], 'o2': [0, -1], 'o3': [7, 8, 10, 11]}
И мне нужны все комбинации каждого элемента в каждом списке. Для этого я использую продукт:
itertools.product(*d.values())
Перебор каждой комбинации дает:
(7, 0, 1)
(7, 0, 2)
(7, 0, 3)
Мне нужно отслеживать исходный список каждого элемента в итоговом комбинированном списке. Мне нужно сказать, что 7
принадлежит к 'o3'
, 0
- к 'o2'
, а 1
- к 'o1'
. Элементы не уникальны.
Как я мог это сделать?
Я пробовал это:
r = [[(k, x) for x in v] for k, v in d.iteritems()]
itertools.product(*r)
Это дает:
(('o3', 7), ('o2', 0), ('o1', 1))
(('o3', 7), ('o2', 0), ('o1', 2))
(('o3', 7), ('o2', 0), ('o1', 3))
Но не думаю, что это слишком элегантно.
Используйте collections.OrderedDict
, чтобы указать порядок ваших значений.
Ниже приведены несколько способов сделать это.
from collections import OrderedDict
od1 = OrderedDict(sorted(d.items()))
od2 = OrderedDict([('o1', [1, 2, 3]), ('o2', [0, -1]), ('o3', [7, 8, 10, 11])])
Затем, когда вы запустите itertools.product
, порядок итераций будет соответствовать вашему порядку OrderedDict
.
Я думаю, инвертируя пару словарных ключей, вы можете позже удобно обратиться к возвращенному словарю:
dd = dict()
for key, val in d.items():
for element in val:
if not dd.get(element):
dd[element] = list()
dd[element].append(key)
dd
# {1: ['o1'], 2: ['o1'], 3: ['o1'], 0: ['o2'], -1: ['o2'], 7: ['o3'], 8: ['o3'], 10: ['o3'], 11: ['o3']}
dd[1]
# ['o1']
Поскольку значения в исходном словаре не уникальны, вы хотите, чтобы значения нового словаря были списками.
Обновлено:
Чтобы вывод был согласован с продуктом:
p = list(product (*d.values())
[tuple(dd[i] for i in val) for val in p]
# [(['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3']), (['o1'], ['o2'], ['o3'])]
Вы можете использовать ту же индексацию, чтобы получить пару "ключ-значение".