M.wol
M.wol

Reputation: 1311

Python dict comprehension convert list of tuples of dictionaries and integers into list of dictionaries

I have list of dictionaries and list of integers

x = [
    {
        "name": "tom",
        "job": "judge"
    },
    {
        "name":"bob",
        "job": "policeman"
    }
]
y = [1000, 2200]

I want to zip them and add y elements to dictionaries as "payroll": y_element The desired output would be:

[
    {
        "name": "tom",
        "job": "judge",
        "payroll": 1000
    },
    {
        "name":"bob",
        "job": "policeman",
        "payroll": 2200
    }
]

I actually achieved that by:

z = zip(x, y)
for i in z:
    i[0]["payroll"] = i[1]

z = [i[0] for i in z]

But I was wondering whether it could be done in dict comprehension in list comprehension. This is what I tried so far:

z = [{k: v, "value": o} for d, o in z for k, v in d.items()]

Obviously it is wrong because the output is:

{'name': 'bob', 'job': 'policeman', 'value': 2}

Upvotes: 4

Views: 231

Answers (3)

mozway
mozway

Reputation: 260455

With python ≥3.9 you can use dictionary merging with the | operator:

out = [d | {'payroll': p} for d, p in zip(x, y)]

output:

[{'name': 'tom', 'job': 'judge', 'payroll': 1000},
 {'name': 'bob', 'job': 'policeman', 'payroll': 2200}]

Upvotes: 4

The Pjot
The Pjot

Reputation: 1859

Speaking as someone who has done 100's (if not more..) of reviews over many years of other peoples code. I think the question should be whether you should try to do this in any form of comprehension. Readability of code is key, if nobody understand what you're trying to do, it is simply not maintainable. You'll forgot what it was supposed to do, comments will go out of sync (if any are there to begin with) with the code.

The most readable version in my opinion is the one that keeps it simple. Do note this does modifying the x in place. S

for index, dikt in enumerate(x):
    dikt["payroll"] = y[index] # fetch the payroll from the other list using the index

What would the gain be with one liner over this? One line and less readability. Yes, and showing you know 'comprehension', good for you! Nobody will give you a price over it. And me as a reviewer will add a issue saying "Don't do this. It decrease readability".

So pretty please; don't.

Disclaimer: Yes, there are always cases where a simple comprehension is also just good enough. But I've seen construction where people start looping over the result of a comprehensions and then further filter out the result.

Simple is better than complex. Complex is better than complicated.

Upvotes: 3

Ch3steR
Ch3steR

Reputation: 20669

You can merge the dict with the required data using ** here.

[{**d, 'payroll':i} for d, i in zip(x, y)]

# [{'name': 'tom', 'job': 'judge', 'payroll': 1000},
#  {'name': 'bob', 'job': 'policeman', 'payroll': 2200}]

Upvotes: 9

Related Questions