7

Given a list:

source = [{'A':123},{'B':234},{'C':345}]

I need a dict from this list in the format:

newDict  = {'A':123,'B':234,'C':345}

What is the syntactically cleanest way to accomplish this?

Donald Duck
  • 8,409
  • 22
  • 75
  • 99
NTP
  • 91
  • 1
  • 8
  • Possible duplicate of [Convert a list to a dictionary in Python](http://stackoverflow.com/questions/4576115/convert-a-list-to-a-dictionary-in-python) – Ben Hare Mar 02 '17 at 14:43
  • 1
    Certainly not the most "syntactically clean" way, but somewhat fun: `reduce(lambda d, cur: d.update(cur) or d, source, {})` – miradulo Mar 02 '17 at 15:11
  • What if you have a list `[{'A': 123}, {'A': 456}]`? Should the result be `{'A': 123}` or `{'A': 456}`? – tobias_k Mar 02 '17 at 15:31
  • if source = [{'A':123},{'B':234},{'C':345},{'A':123}] Then we have issues. Forming dict duplicate keys not possible. Complete data cannot be analyzed in that case – NTP Mar 02 '17 at 15:37
  • I'd rename the question along the lines of "merging a list of dict entries into one dict" – matanster Jun 12 '18 at 08:22

3 Answers3

10

Use a dict-comprehension:

>>> l = [{'A':123},{'B':234},{'C':345}]
>>> d = {k: v for dct in l for k, v in dct.items()}
>>> d
{'A': 123, 'B': 234, 'C': 345}

However it's probably opinion-based if that's the "syntactically cleanest way" but I like it.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
1

Here's an additional approach, provided here to give you a flavor for how Python implements the functional programming technique called reduction, via the reduce() function. In Python 3, reduce() is in the functools package. In Python 2, reduce() is a built-in function. I use Python 3 in the example below:

from functools import reduce    # don't import if you are using Python 2

def updater(dict_orig, dict_add):
    dict_orig.update(dict_add)
    return dict_orig

new_dict = reduce(updater, l, dict())

The first argument to reduce() is the function to operate on the iterable, the second is the iterable itself (your list l), and the third is the optional initializer object to put at the beginning of the list to reduce.

Each step of the reduction requires an object to be operated on: namely, the result of the previous step. But dict.update() does not return anything, so we need the updater() function above, which performs the update and then returns the dict being updated, thus providing the required object for the next step. Were it not for dict.update() not having a return value, this would all be a one-liner.

Because dict.update() operates directly on the original dict, we need that optional empty dict() initializer object to start out the reduction - without it, the first dict in your original l list would be modified.

For all these reasons, I like @MSeifert's dict-comprehension approach much better, but I posted this anyway just to illustrate Python reduction for you.

sparc_spread
  • 10,643
  • 11
  • 45
  • 59
0

If you use it often, you might want to define a merge function, which you can then pass to reduce :

from functools import reduce # Needed for Python3
source = [{'A':123},{'B':234},{'C':345}]

def merge(a,b):
    d = a.copy()
    d.update(b)
    return d

print(reduce(merge, source))
#=> {'A': 123, 'C': 345, 'B': 234}
Eric Duminil
  • 52,989
  • 9
  • 71
  • 124