Удалить дубликаты словарей из списка и вычесть значение ключей дубликата элемента - PullRequest
0 голосов
/ 31 января 2019

У меня есть список диктов, и я хотел бы удалить дикты с одинаковым ключом и вычесть пары значений.

Для этого списка:

[{'chair': 4}, {'tv': 5}, {'chair': 3}, {'tv': 2}, {'laptop': 2}]

Я быхотел бы вернуть это:

[{'chair': 1}, {'tv': 3}, {'laptop': 2}]

Ответы [ 4 ]

0 голосов
/ 31 января 2019

Вы можете создать defaultdict списков, затем использовать понимание списка:

from collections import defaultdict

dd = defaultdict(list)
for d in data:
    k, v = next(iter(d.items()))
    dd[k].append(v)

res = [{k: v if len(v) == 1 else v[0] - sum(v[1:])} for k, v in dd.items()]

print(res)
# [{'chair': 1}, {'tv': 3}, {'laptop': [2]}]
0 голосов
/ 31 января 2019

defaultdict из коллекций может пригодиться.Это решение будет охватывать случаи, когда в списке содержится более 2 символов одного и того же ключа.

from collections import defaultdict
ls = defaultdict(list)
d = [{'chair': 4}, {'tv': 5}, {'chair': 3}, {'tv': 2}, {'laptop': 2}]


# Creating a list of all values under one key

for dic in d:
    for k in dic:
            ls[k].append(dic[k])

print(ls)
defaultdict(<class 'list'>, {'chair': [4, 3], 'tv': [5, 2], 'laptop': [2]})

# safe proofing for negative values on subtraction    
for k in ls:
    ls[k].sort(reverse=True)
    ls[k] = ls[k][0] - sum(ls[k][1:])

print(ls)
defaultdict(<class 'list'>, {'chair': 1, 'tv': 3, 'laptop': 2})
0 голосов
/ 31 января 2019

Следующий фрагмент использует только стандартные модули:

a= [{'chair': 4}, {'tv': 5}, {'chair': 3}, {'tv': 2}, {'laptop': 2}]

print("Input:", a)

b=dict()
for element in a:
    for k,v in element.items():
        try:
          # you didn't specify the subtracted element order,   
          # so I'm subtracting BIGGER from SMALLER using simple abs() :)
          b[k] = abs(b[k] - v) 
        except:
          b[k] = v

print("Output:", b)

# restore original structure
c = [ dict({item}) for item in b.items() ]

print("Output:", c)

И демо:

('Input:', [{'chair': 4}, {'tv': 5}, {'chair': 3}, {'tv': 2}, {'laptop': 2}])
('Output:', {'tv': 3, 'chair': 1, 'laptop': 2})
('Output:', [{'tv': 3}, {'chair': 1}, {'laptop': 2}])

РЕДАКТИРОВАТЬ: Добавлен вторичный выход C для реструктуризации B, аналогично A

0 голосов
/ 31 января 2019

Вы можете сделать это следующим образом, создав промежуточный дикт для эффективности:

dicts_list = [{'chair': 4}, {'tv': 5}, {'chair': 3}, {'tv': 2}, {'laptop': 2}]

out = {}
for d in dicts_list:
    for key, val in d.items():
       if key in out:
           out[key] -= val
       else:
           out[key] = val

out_list = [ {key:val} for key, val in out.items()]

print(out_list)
# [{'tv': 3}, {'chair': 1}, {'laptop': 2}]

Но вас может заинтересовать этот промежуточный дикт в качестве вывода:

print(out)
# {'tv': 3, 'chair': 1, 'laptop': 2}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...