Вычесть значение словаря из ключа - PullRequest
0 голосов
/ 29 октября 2018

У меня есть словарь, подобный этому:

a = {(8, 9): [[0, 0], [4, 5]], (3, 4): [[1, 2], [6, 7]]}

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

Например:

new_key[0] = 8 - 0+4 = 4, new_key[1] = 9 - (0+5) = 4

Следовательно, новый ключ становится (4, 4) и заменяет (8, 9)

Я не могу понять, как получить доступ к списку списков, который является значением ключа!

Есть идеи, как это сделать?

Ответы [ 6 ]

0 голосов
/ 30 октября 2018

Следующий код будет работать так же хорошо с любым размером набора ключей (2, 5, 87 и т. Д.)

Нет простого способа переименовать ключ словаря, но вы можете вставить новый ключ и удалить старый. Это не рекомендуется по нескольким причинам:

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

  • будьте осторожны, когда вы перебираете словарь при его изменении

Если вам нужен результат словаря, самое безопасное - создать совершенно новый словарь на основе a, как это было сделано здесь.

Проблема, которую вы пытаетесь решить, легче перенести в словарь.

После вычисления нового ключа (8, 9): [[0, 0], [4, 5]] должно стать:

(8 - sum([0, 4]), 9 - sum([0, 5])): [[0, 0], [4, 5]] 

Теперь посмотрим, как помогает транспонирование:

transposed([[0, 0], [4, 5]]) == [[0, 4], [0, 5]]

, тогда новый key[0] расчет:

key[0] - sum(transposed(values)[0])

и новый key[1] расчет:

key[1] - sum(transposed(values)[1])

Таким образом, транспонирование облегчает вычисления.

Словари Python не могут иметь списки в качестве ключей (списки не могут быть хэшируемыми ), поэтому я собрал ключ в виде списка, а затем преобразовал его в кортеж в конце.

a = {
    (8, 9): [[0, 0], [4, 5]],
    (3, 4): [[1, 2], [6, 7]]
}

def transpose(m):
    return list(zip(*m))

results = {}
for source_keys, source_values in a.items():
    transposed_values = transpose(source_values)
    key = []
    for n, key_item in enumerate(source_keys):
        subtractables = sum(transposed_values[n])
        key.append(key_item - subtractables)
    results[tuple(key)] = source_values

print(results)

>>> python transpose.py
{(4, 4): [[0, 0], [4, 5]], (-4, -5): [[1, 2], [6, 7]]}
0 голосов
/ 29 октября 2018

Попробуйте:

b = {}
for key, value in a.items():
    new_key = key[0]-(value[0][0]+value[1][0])
    new_key_1 = key[1]-(value[0][1]+value[1][1])
    u_key = (new_key, new_key_1)
    b[u_key]=value
print(b)
0 голосов
/ 29 октября 2018

Следующее решение работает с тремя допущениями:

  1. Ключи являются итерациями целых чисел
  2. Значения являются итерациями итераций целых чисел
  3. Внутренние итерации каждого значения имеют ту же длину, что и соответствующий ключ

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

Вы хотите транспонировать значения, чтобы было проще вычислить сумму. Идиома zip(*value) позволяет вам сделать это довольно легко. Затем вы сопоставляете сумму с этим и вычитаете результат из элементов ключа.

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

from operator import sub
from itertools import starmap

a = {(8, 9): [[0, 0], [4, 5]], (3, 4): [[1, 2], [6, 7]]}
b = {
    tuple(starmap(sub, zip(k, map(sum, zip(*v))))): v
    for k, v in a.items()
}

Результат

{(4, 4): [[0, 0], [4, 5]], (-4, -5): [[1, 2], [6, 7]]}

Вот ссылка IDEOne , с которой можно играть.

Полная версия цикла будет выглядеть так:

b = {}
for k, v in a.items():
    vt = zip(*v)  # transposed values
    sums = map(sum, vt)  # sum of the 1st elements, 2nd elements, etc
    subs = zip(k, sums)  # match elements of key with sums to subtract
    diffs = starmap(sub, subs)  # subtract sums from key
    new_key = tuple(diffs)  # evaluate the generators
    b[new_key] = value
0 голосов
/ 29 октября 2018

Итерация по словарю для получения ключей и значений и создания нового b. Затем просто укажите a на новый словарь b

a = {(8, 9): [[0, 0], [4, 5]], (3, 4): [[1, 2], [6, 7]]}
b = {}
for key, val in a.items():
    new_key = (key[0]-(val[0][0]+val[1][0]), key[1]-(val[0][1]+val[1][1]))
    b[new_key] = val
a = b
del b
0 голосов
/ 29 октября 2018
for key in list(a.keys()):
    new_key = []
    new_key.append(key[0] - (a[key][0][0] + a[key][1][0]))
    new_key.append(key[1] - (a[key][0][1] + a[key][1][1]))
    a[new_key] = a.pop(key) # pop() returns the value
0 голосов
/ 29 октября 2018

См. Доступ к элементу в списке списков для индексации списка.

Для вашего конкретного случая это должно работать

b = {(k[0]-v[0][0]-v[1][0], k[1]-v[0][1]-v[1][1]):v for k, v in a.items()}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...