Удаление дубликатов ключей из словаря Python, но суммирование значений

У меня есть словарь на питоне

d = {tags[0]: value, tags[1]: value, tags[2]: value, tags[3]: value, tags[4]: value}

представьте, что этот дикт в 10 раз больше, он имеет 50 ключей и 50 значений. Дубликаты могут быть найдены в этих тегах, но даже тогда значения имеют важное значение. Как я могу просто обрезать его, чтобы получить новый dict без дубликатов ключей, но с суммой значений вместо этого?

d = {'cat': 5, 'dog': 9, 'cat': 4, 'parrot': 6, 'cat': 6}

результат

d = {'cat': 15, 'dog': 9, 'parrot': 6}

 Paul Seeb18 мая 2012 г., 16:48
Вы должны рассмотреть вопрос об изменении имени Вопроса, так как словари не могут иметь повторяющиеся ключи в первую очередь
 Niek de Klein18 мая 2012 г., 16:30
У вас нет этого словаря, все ключи являются уникальными.
 Andy♦18 мая 2012 г., 16:31
Вы не можете иметь дубликаты в словаре Python

Ответы на вопрос(8)

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

tps = [('cat',5),('dog',9),('cat',4),('parrot',6),('cat',6)]
result = {}
for k, v in tps:
    result.update({k:v})
for k in result:
    print "%s: %s" % (k, result[k]) 

Вывод будет выглядеть так: dog: 9 parrot: 6 cat: 6

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

>>> from collections import Counter
>>> list_a = ["A", "A", "B", "C", "C", "A", "D"]
>>> list_b = ["B", "A", "B", "C", "C", "C", "D"]
>>> c1 = Counter(list_a)
>>> c2 = Counter(list_b)
>>> c1
Counter({'A': 3, 'C': 2, 'B': 1, 'D': 1})
>>> c2
Counter({'C': 3, 'B': 2, 'A': 1, 'D': 1})
>>> c1 - c2
Counter({'A': 2})
>>> c1 + c2
Counter({'C': 5, 'A': 4, 'B': 3, 'D': 2})
>>> c_diff = c1 - c2
>>> c_diff.update([77, 77, -99, 0, 0, 0])
>>> c_diff
Counter({0: 3, 'A': 2, 77: 2, -99: 1})

Как вы можете видеть, это ведет себя как набор, который сохраняет количество вхождений элемента в качестве значения. Хм, а как насчет использования словаря вместо списка? Словарь сам по себе представляет собой подобную множеству структуру, в которой для значений, которые нам не нужны, должны быть числа, так как это будет обрабатываться? Давайте взглянем.

>>> dic1 = {"A":"a", "B":"b"}
>>> cd = Counter(dic1)
>>> cd
Counter({'B': 'b', 'A': 'a'})
>>> cd.update(B='bB123')
>>> cd
Counter({'B': 'bbB123', 'A': 'a'})


>>> dic2 = {"A":[1,2], "B": ("a", 5)}
>>> cd2 = Counter(dic2)
>>> cd2
Counter({'B': ('a', 5), 'A': [1, 2]})
>>> cd2.update(A=[42], B=(2,2))
>>> cd2
Counter({'B': ('a', 5, 2, 2), 'A': [1, 2, 42, 42, 42, 42]})
>>> cd2 = Counter(dic2)
>>> cd2
Counter({'B': ('a', 5), 'A': [1, 2]})
>>> cd2.update(A=[42], B=("new elem",))
>>> cd2
Counter({'B': ('a', 5, 'new elem'), 'A': [1, 2, 42]})

Как видите, значение, которое мы добавляем / меняем, должно быть одного типа вupdate или это бросаетTypeError. As for your particular case just go with the flow

>>> d = {'cat': 5, 'dog': 9, 'cat': 4, 'parrot': 6, 'cat': 6}
>>> cd3 = Counter(d)
>>> cd3
Counter({'dog': 9, 'parrot': 6, 'cat': 6})
cd3.update(parrot=123)
cd3
Counter({'parrot': 129, 'dog': 9, 'cat': 6})
tps = [('cat',5),('dog',9),('cat',4),('parrot',6),('cat',6)]

from collections import defaultdict

dicto = defaultdict(int)

for k,v in tps:
    dicto[k] += v

>>> dicto
defaultdict(<type 'int'>, {'dog': 9, 'parrot': 6, 'cat': 15})

tps = [('cat',5),('dog',9),('cat',4),('parrot',6),('cat',6)]
result = {}
for k, v in tps:
  result[k] = result.get(k, 0) + v
 18 мая 2012 г., 16:43
Это на самом деле отлично. О чем я думал, но не мог понять :)
 24 февр. 2014 г., 18:34
track = [] для ключа, значение в neop1: track.append (ключ) result [key] = (result.get (key, 0) + float (value)) / track.count (key) # это даст вам средний

чего вы пытаетесь достичь, но класс Counter может помочь вам в том, что вы пытаетесь сделать: http://docs.python.org/dev/library/collections.html#collections.Counter

но делается со списком, или лучше всего может обеспечить понимание

data = []
        for i, j in query.iteritems():
            data.append(int(j))    
        try:
            data.sort()
        except TypeError:
            del data
        data_array = []
        for x in data:
            if x not in data_array:
                data_array.append(x)  
        return data_array

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

tps = [('cat',5),('dog',9),('cat',4),('parrot',6),('cat',6)]
result = {}
for k,v in tps:
    try:
        result[k] += v
    except KeyError:
        result[k] = v

>>> result
{'dog': 9, 'parrot': 6, 'cat': 15}

поменял мой на более явный try-кроме обработки. Хотя это очень лаконично

 18 мая 2012 г., 16:58
Наверное, дело вкуса. я хотел бы использоватьdefaultdict хоть. Я предпочитаю читабельность этого. Также он предназначен для таких случаев.
 18 мая 2012 г., 16:48
Почему бы не использоватьcollections.defaultdict ?
 18 мая 2012 г., 16:51
Почему ты хотя? Я чувствую, что сделать импорт для чего-то столь же простого, как это, чрезмерно усложняет решение. Ответ Алфе - очевидный выбор здесь. Мой делает то же самое, что и его, просто более явный в смысле
 20 мая 2016 г., 11:57
@PaulSeeb Спасибо за заслуги, но на самом деле в любом довольно крупном проекте, которым я пользуюсьdefaultdict в любом случае для какой-то задачи, так что импорт все равно произойдет. Использование его вместо моего решения имеет несколько преимуществ. Одно: рассмотрим комплексk лайк(n+5) / len(x), В моем решении это было быresult[(n+5) / len(x)] = result.get((n+5) / len(x), 0) + v таким образом удваивая код дляk, Введение локальной переменной может исправить это, ноd[k] = d.get(k, 0) + v может все еще сделать двойной поиск в диктанте. Простоd[k] += v чище и понятнее, поэтому в реальном коде я бы предпочелdefaultdict.

tuple пар ключ-значение.

[('dog',1), ('cat',2), ('cat',3)]

Ваш ответ на вопрос