Aboottogo
Aboottogo

Reputation: 355

How to update a list of dictionaries without a loop?

I have a list of N dictionaries, along with a list of N strings. For each dictionary in the former, I would like to append/update a key-value pair with the corresponding string from the later.

For example:

names = [{'First':'John','Last':'Doe'} , {'First':'Jane','Last':'Doe'}]
ages = ['21','32']

The following loop works:

for i,j in zip(names,ages):
    i.update({'Age':j})
    print(i)

Partly for the intellectual challenge, but partly to accommodate eventual parallel processing, I would like to solve the same problem without a loop. Neither of my two attempts worked; both returned a list of None types:

First attempt:

f = lambda x: x[0].update({'Age':x[1]})
out = map(f,zip(names,ages))
for i in out: print(i)

Second attempt:

out = (i.update({'Age':j}) for i,j in zip(names,ages))
for i in out: print(i)

What gives?

Upvotes: 0

Views: 1246

Answers (1)

Green Cloak Guy
Green Cloak Guy

Reputation: 24691

Using the dict unpacking operator **, it should be possible to return a merged dict as the result of a map, without modifying the original at all.

f = lambda x: {**x[0], 'Age': x[1]}
out = map(f,zip(names,ages))
print(list(out))
# [{'First': 'John', 'Last': 'Doe', 'Age': '21'}, 
#  {'First': 'Jane', 'Last': 'Doe', 'Age': '32'}]

This is a slightly uncommon idiom that you can use to merge dicts on the fly. When it releases in a few months, Python 3.9 will be adding an overload for the | operator that would allow you to do something like x[0] | {'Age': x[1]} to achieve the same result more clearly, but for now this should serve your purposes.

This should make the solution easier to parallelize, though keep in mind a for loop can perfectly well be used for parallelization, as long as each element is independent of the others - you can just split the list into chunks and hand one chunk to each parallel process. The only benefit of this approach, as opposed to the one you're already using, is that the various parallel processes would be no longer writing to the same datastructure in memory.

Upvotes: 2

Related Questions