2016-08-26 13 views
1

У меня есть несколько словарей, и я хочу напечатать таблицу, в которой каждая строка является уникальной комбинацией клавиш во всех словарях. Для каждой строки я также хочу напечатать сумму значений для ключей в этой конкретной комбинации.Распечатайте список каждой комбинации клавиш словаря с соответствующей суммой значений ключа справа

Так что, если у меня есть эти словари:

dict1 = {"Main": 8, "Optional": 6, "Obscure": 4} 
dict2 = {"Global": 8, "Regional": 4, "Local": 2} 
... 

Вывод будет выглядеть следующим образом (отсортировано по сумме высшего к низшему):

Main, Global, 16 
Optional, Global, 14 
Main, Regional, 12 
Obscure, Global, 12 
Main, Local, 10 
Optional, Regional, 10 
Optional, Local, 8 
Obscure, Regional, 8 
Obscure, Local, 6 

Из того, что я прочитал, itertools. продукт будет тем, что я ищу, но ни один из существующих вопросов не является моим прецедентом, и я боюсь даже начать.

Любая помощь будет оценена по достоинству.

Благодаря

ответ

1

Вы прочитали правильно. Просто добавьте sorted():

from itertools import product 
from operator import itemgetter 

results = [(k1, k2, dict1[k1] + dict2[k2]) 
      for k1, k2 in product(dict1.keys(), dict2.keys())] 

for k1, k2, sum_ in sorted(results, key=itemgetter(2), reverse=True): 
    print(k1, k2, sum_, sep=', ') 
+0

Это сработало отлично! У меня много словарей, поэтому мне пришлось добавлять дополнительные переменные и корректировать значения itemgetter, но в остальном они идеальны. Большое вам спасибо :) – Brandon

1

Я думаю, что это будет что-то вроде:

import itertools 

dict1 = {"Main": 8, "Optional": 6, "Obscure": 4} 
dict2 = {"Global": 8, "Regional": 4, "Local": 2} 

merged = {'{}, {}'.format(prod[0], prod[1]): dict1[prod[0]] + dict2[prod[1]] 
      for prod in itertools.product(dict1, dict2)} 

for k, v in merged.items(): 
    print('{}: {}'.format(k, v)) 

Выход:

Optional, Regional: 10 
Main, Regional: 12 
Optional, Local: 8 
Main, Global: 16 
Optional, Global: 14 
Main, Local: 10 
Obscure, Regional: 8 
Obscure, Global: 12 
Obscure, Local: 6 
1

Использование product из itertools на словарных элементов(), где вы можете получить как ключ и значение в то же время, и с комбинацией пар ключ-значение вы можете построить окончательный результат довольно просто:

from itertools import product 
sorted([(k1, k2, v1+v2) for (k1, v1), (k2, v2) in product(dict1.items(), dict2.items())], \ 
     key = lambda x: x[2], reverse=True) 

# [('Main', 'Global', 16), 
# ('Optional', 'Global', 14), 
# ('Obscure', 'Global', 12), 
# ('Main', 'Regional', 12), 
# ('Main', 'Local', 10), 
# ('Optional', 'Regional', 10), 
# ('Obscure', 'Regional', 8), 
# ('Optional', 'Local', 8), 
# ('Obscure', 'Local', 6)] 
+1

Этот ответ является более эффективным, чем остальные размещены до сих пор, так как это позволяет избежать ненужных 'dict' Lookups с помощью' .items() '(хотя вы должны использовать '.viewitems()' на Py2 для минимизации временных '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ' Нужно добавить шаг сортировки, хотя ('operator.itemgetter (2)' для функции 'key'). – ShadowRanger

+0

@ShadowRanger, хотя верно, разница несколько минимальна (2,29 мкс против 2,33 мкс, например, py3). Но использование 'items()' и распаковка - приятный штрих. –

1

Этот метод построен для поддержки переменного количества словарей. Вы передаете словари методу get_product_sums(), который затем создает декартово произведение из кортежа словарей.

Затем мы проследуем через наш новый subitem, чтобы рассчитать суммы, выполнив поиск в нашем flattened, который сейчас является только 1-го словарем. Затем мы сортируем по сумме и возвращаем отсортированный список кортежей для нашего окончательного result.

from itertools import product 

def get_product_sums(* args): 
    result = [] 
    flattened = {k:v for d in args for k, v in d.items()} 
    for subitem in product(* args, repeat=1): 
     data = subitem + (sum(flattened[key] for key in subitem),) 
     result.append(data) 
    return sorted(result, key=lambda x: x[-1], reverse=True) 

Пример вывода:

>>> dict1 = {"Global": 8, "Regional": 4, "Local": 2} 
>>> dict2 = {"Main": 8, "Optional": 6, "Obscure": 4} 
>>> for item in get_product_sums(dict1, dict2): 
...  print ', '.join(str(element) for element in item) 
Global, Main, 16 
Global, Optional, 14 
Global, Obscure, 12 
Regional, Main, 12 
Local, Main, 10 
Regional, Optional, 10 
Local, Optional, 8 
Regional, Obscure, 8 
Local, Obscure, 6 
+0

* args можно использовать вместо кортежа словарей –

+0

@DiegoAllen Наверняка! Я оставил его как кортеж, потому что я не уверен, каким образом он обрабатывает данные. – ospahiu