update values in a list of dictionaries

Question:

I have the following list:

list_dict = [
        {'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
        {'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
        {'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
        {'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': []}
    ]

I would like to add a hobby to R2:

for i in range(len(list_dict)):
    people = list_dict[i]
    if people['name'] == 'R2':
        people['hobbies'] = ['lubrication']
print(list_dict)

I got what I was expecting but as a newbie I’d like to learn a few easy tricks to make it shorter.

Asked By: user1166251

||

Answers:

You can just iterate over the list and condense the if statement:

for person in list_dict:
    person['hobbies'] = ['lubrication'] if person['name'] == 'R2' else person['hobbies']
Answered By: The Thonnu

I’d express as:

people = {person['name']: person for person in list_dict}

people['R2']['hobbies'] += ['lubrication']  # reads nicely as "add a hobby to R2"

For all those hung up on the academic concern of "potential people with same name", although the "Leetcode answer" would be:

for person in list_dict:
    if person['name'] == 'R2':
        person['hobbies'] += ['lubrication']

But in practice, remodeling data to have & use primary keys is probably what you want in most cases.

Answered By: Kache

there is no need to loop over the lenght, you can loop through the list and you can condense with a one-liner if statement

#!usr/bin/python3
from pprint import pprint
for person in list_dict:
    person['hobbies'].append('lubrification') if person['name'] == 'R2' else ...
pprint(list_dict)
>>> [
        {'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
        {'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
        {'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
        {'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': ["lubrification"]}
    ]

you can also do this with a comprehension:

[person['hobbies'].append('lubrification') for person in list_dict if person['name']]

But, if you just want to change one, you can use this code:

m = next(i for i,person in enumerate(list_dict) if person["name"]=="R2")
list_dict[m]["hobbies"].append("lubrification")
Answered By: XxJames07-

There are some other answers here but in my eyes they don’t really help a newbie seeking to shorten his code. I don’t suggest to use the below proposed shortening except the looping over items in list instead of using indices, but to give here an answer with some maybe worth to know ‘tricks’ (you can have more than one name pointing to same variable/object, you can iterate directly over items of a list instead using indices) to a newbie here a shortened version of the code:

for p in l: 
    if p[n]=='R2': p[h]=['lubrication']
print(l)

and below all of the code using the proposed shortening with comments pointing out the ‘tricks’:

list_dict = [
        {'name': 'Old Ben', 'age': 71, 'country': 'Space', 'hobbies': ['getting wise']},
        {'name': 'Han', 'age': 26, 'country': 'Space', 'hobbies': ['shooting']},
        {'name': 'Luke', 'age': 24, 'country': 'Space', 'hobbies': ['being arrogant']},
        {'name': 'R2', 'age': 'unknown', 'country': 'Space', 'hobbies': []},
        {'name': 'R2', 'age': 15, 'country': 'Alduin', 'hobbies': []}
    ]
l = list_dict; n='name'; h='hobbies'

# I would like to add a hobby to R2:
"""
for i in range(len(list_dict)):
    people = list_dict[i]
    if people['name'] == 'R2':
        people['hobbies'] = ['lubrication']
"""
# I got what I was expecting but as a newbie I'd like to learn a few 
# easy tricks to make it shorter: 

for p in l: # loop over items in list instead of using indices 
    if p[n]=='R2': p[h]=['lubrication'] # use short variable names
    #    ^-- give  --^ long string constants short names 
print(l)
Answered By: Claudio
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.