Вы можете отсортировать список a
так, чтобы одинаковые клавиши были группами, а самые большие значения были последними.Затем добавьте значения так, чтобы последним значением было значение, оставленное в dict:
>>> a = [{u'a': 1}, {u'a': 2}, {u'a': 1}, {u'b': 2}, {u'b': 1}, {u'c': 1}, {u'c': 1}]
>>> {k:v for k,v in (x.items()[0] for x in sorted(a))}
{u'a': 2, u'c': 1, u'b': 2}
Или альтернативный синтаксис:
>>> dict(x.items()[0] for x in sorted(a))
Для синтаксиса Python 2 и 3:
>>> {k:v for k,v in (sorted(list(x.items())[0] for x in a))}
{'a': 2, 'b': 2, 'c': 1}
>>> dict(sorted(list(x.items())[0] for x in a))
{'a': 2, 'b': 2, 'c': 1}
Из комментариев: что здесь происходит?
Сначала давайте подойдем к более поучительному примеру:
>>> a = [{u'a': -1}, {u'a': -11}, {u'a': -3}, {u'b': 0}, {u'b': 100}, {u'c': 3}, {u'c': 1}]
Итак, желаемоеРезультатом здесь являются ключи (для Python 3, которые поддерживают порядок в dict или с OrderedDict): i) ключи в группах отсортированных значений и затем ii) значения, интерпретируемые как числа в возрастающих значениях.
Так что попробуйте этоfirst:
>>> sorted(list(x.items())[0] for x in a)
[('a', -11), ('a', -3), ('a', -1), ('b', 0), ('b', 100), ('c', 1), ('c', 3)]
Разбейте его на части:
sorted(list(x.items())[0] for x in a)
^ ^ comprehension of
^ a list of one element dicts
^ ^ ^ convert to a two element tuple
^ sort the tuple first by key, then by value
Так что это работает, сортируя кортежи сначала по ключам, а затем по значениям.
Что приводит к альтернативному решению с использованием groupby
:
>>> from itertools import groupby
>>> for k,v in groupby(sorted(list(x.items())[0] for x in a), key=lambda t: t[0]):
... print(k, max(v))
...
a ('a', -1)
b ('b', 100)
c ('c', 3)
Решение groupby
будет значительно более удобным для памяти, так как оно не создает дополнительного списка.Первое решение, скорее всего, будет быстрее с меньшим списком диктов, поскольку сортировка проще (но вам нужно это проверить.)
Это не требуется в решении, которое ядал, чтобы ключи были сгруппированы (требуется для работы groupby
).Это тоже работает:
>>> sorted((list(x.items())[0] for x in a), key=lambda t: t[1])
[('a', -11), ('a', -3), ('a', -1), ('b', 0), ('c', 1), ('c', 3), ('b', 100)]
Затем превратите его в dict
с функцией построения dict.Напомним, что список кортежей занимает (key, value)
:
>>> dict(sorted((list(x.items())[0] for x in a), key=lambda t: t[1]))
{'a': -1, 'b': 100, 'c': 3}