2013-10-28 3 views
0

Есть ли простой способ сравнить 2 значения в словаре со всеми другими значениями? Например, если у меня есть Dict:Сравнение двух значений в dict со всеми другими значениями

dict = {A:12, B:1, C:14, D:13, E:3, F: 4} 

Я хочу найти все значения, которые могут быть добавлены вместе, чтобы равняться другие значения. Например. A + B = D, поэтому A, B и D будут возвращены.

+1

Если на "легкий путь" вы имеете в виду встроенную функцию, то нет. Вам придется идти «с трудом» сравнения самих дополнений. –

+0

Может ли быть несколько значений по обе стороны от уравнения? (Например, 'A + D + B = C + A' - вы хотите найти такие значения)? –

+0

FYI, это неправильный синтаксис словаря Python - вы хотите использовать кавычки вокруг своих ключей и свои значения, если они являются строками. –

ответ

7

Использование itertools.combinations:

d = {'A':12, 'B':1, 'C':14, 'D':13, 'E':3, 'F': 4} 

import itertools 
for a, b, c in itertools.combinations(sorted(d, key=d.get), 3): 
    if d[a] + d[b] == d[c]: 
     print(a,b,c) 

B E F 
B A D 
B D C 

UPDATE

Если вы хотите использовать дубликаты itertools.combinations_with_replacement вместо:

d = {'A':1, 'B':2, 'C':4} 

import itertools 
for a, b, c in itertools.combinations_with_replacement(sorted(d, key=d.get), 3): 
    if d[a] + d[b] == d[c]: 
     print(a,b,c) 

A A B 
B B C 

Почему sorted используются?

Сравнение x + y == z не имеет смысл, если x или y это больше, чем z. (при условии, что все значения являются положительными целыми числами). Я использовал sorted для упорядочивания данных; x <= y <= z.

Другой побочный эффект сортировки: если A + B == C имеет значение True, B + A == C также является истинным. Но используя sorted, печатается только один.


BTW, Не используйте dict как переменное имя. Это тени встроены в функцию dict.

+0

Я предполагал, что дубликаты будут разрешены, например, если 'B = 2', то' B + B = D'. Возможно, вы захотите объяснить, почему здесь требуется сортировка. –

+0

Как сортируется сортировка на основе значения, когда 'key' является' d.get'? Будет ли ключевая функция передаваться фактическими ключами из dict? – thefourtheye

+0

@thefourtheye, да, это делает «сортировать по значению» –

2

Это довольно легко, но не очень эффективно (нормально для небольших dicts)

>>> D = {'A':12, 'B':1, 'C':14, 'D':13, 'E':3, 'F': 4} 
>>> 
>>> from itertools import product 
>>> for i, j, k in product(D.items(), repeat=3): 
...  if i[1] + j[1] == k[1]: 
...   print "{} + {} = {}".format(i[0], j[0], k[0]) 
... 
A + B = D 
B + A = D 
B + E = F 
B + D = C 
E + B = F 
D + B = C 
+0

Он также дает дубликаты. – thefourtheye

+0

@thefourtheye, это была моя интерпретация «всех ценностей». также см. мой комментарий к ответу falsetru –

2

Это работает в O (n^2) на непатологических входах (например, все нули), а не O (n^3), как и другие ответы здесь, и правильно обрабатывает дубликаты.

def addTriples(d): 
    inverse = {v:[] for v in d.itervalues()} 
    for k, v in d.iteritems(): 
     inverse[v].append(k) 

    for k1, v1 in d.iteritems(): 
     for k2, v2 in d.iteritems(): 
      if k1 != k2: 
       for k3 in inverse.get(v1 + v2,()): 
        if k2 != k3: 
         yield (k1, k2, k3) 

d = {'A':12, 'B':1, 'C':14, 'D':13, 'E':3, 'F':4} 
for triple in addTriples(d): 
    print triple 

Удалить k1 != k2 и k2 != k3, если вы хотите, чтобы A + A = B и A + B = A

+0

Ваш код эффективен, но повышает синтаксическую ошибку. – falsetru

+0

@falsetru, вы правы. (Это было правкой, которая стала плохой.) Это исправлено. –

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