Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add another attribute in dictionary inside a one line for loop [duplicate]

I have a list of dictionary and a string. I want to add a selected attribute in each dictionary inside the list. I am wondering if this is possible using a one liner.

Here are my inputs:

saved_fields = "apple|cherry|banana".split('|')
fields = [
    {
        'name' : 'cherry'
    }, 
    {
        'name' : 'apple'
    }, 
    {
        'name' : 'orange'
    }
]

This is my expected output:

[
    {
        'name' : 'cherry',
        'selected' : True
    }, 
    {
        'name' : 'apple',
        'selected' : True
    }, 
    {
        'name' : 'orange',
        'selected' : False
    }
]

I tried this:

new_fields = [item [item['selected'] if item['name'] in saved_fields] for item in fields]
like image 717
simple guy Avatar asked Jul 07 '20 08:07

simple guy


People also ask

How can we add a new item in the existing dictionary data?

You can see, a new item is added in the existing dictionary by using a simple assignment operator. So, you just need to provide the dictionary name, key in brackets and assign a value to it.

Can we store duplicate keys in dictionary Python?

Dictionaries in Python First, a given key can appear in a dictionary only once. Duplicate keys are not allowed.

How can you create a copy of a dictionary modifying the copy should not change the original )?

Use copy() This is a built-in Python function that can be used to create a shallow copy of a dictionary. This function takes no arguments and returns a shallow copy of the dictionary. When a change is made to the shallow copy, the original dictionary will remain unchanged.


1 Answers

I don't necessarily think "one line way" is the best way.

s = set(saved_fields)  # set lookup is more efficient 
for d in fields:
    d['status'] = d['name'] in s

fields
# [{'name': 'cherry', 'status': True},
#  {'name': 'apple', 'status': True},
#  {'name': 'orange', 'status': False}]

Simple. Explicit. Obvious.

This updates your dictionary in-place, which is better if you have a lot of records or other keys besides "name" and "status" that you haven't told us about.


If you insist on a one-liner, this is one preserves other keys:

[{**d, 'status': d['name'] in s} for d in fields]  
# [{'name': 'cherry', 'status': True},
#  {'name': 'apple', 'status': True},
#  {'name': 'orange', 'status': False}]

This is list comprehension syntax and creates a new list of dictionaries, leaving the original untouched.

The {**d, ...} portion is necessary to preserve keys that are not otherwise modified. I didn't see any other answers doing this, so thought it was worth calling out.

The extended unpacking syntax works for python3.5+ only, for older versions, change {**d, 'status': d['name'] in s} to dict(d, **{'status': d['name'] in s}).

like image 108
cs95 Avatar answered Sep 30 '22 00:09

cs95