update json property value using for loop in python?

Viewed 1648

Does python have util loop like in javascript? (eg. map, reduce and filter). Or everything must be done manually using for loop?

I have a simple 2 object records like below

json = [{
    "id": 1, "name": "a"
}, {
    "id": 2, "name": "b"
}]

How can I update name property if id is 2?

for index, x in json:
    if(x[id] == 2)
        //what to do here? change name to 'something'
6 Answers

The straight forward way:

for obj in json:
    if obj['id'] == 2:
        obj['name'] = 'something'

Objects are mutable, so you're directly mutating the object here. This is the simplest way. The typical Javascript equivalent would be:

json.forEach(obj => {
    if (obj.id == 2) {
        obj.name = 'something';
    }
});

The slightly more condensed version:

for obj in (o for o in json if o['id'] == 2):
    obj['name'] = 'something'

This inlines a generator expression which pre-filters the objects to loop over. Alternatively:

for obj in filter(lambda o: o['id'] == 2, json):
    obj['name'] = 'something'

Somewhat equivalent to:

json.filter(o => o.id == 2).forEach(obj => obj.name = 'something')

The even more condensed version:

json = [{**obj, 'name': 'something' if obj['id'] == 2 else obj['name']} for obj in json]

This is a list comprehension which builds a new object and new list, somewhat equivalent to:

json = json.map(o => ({...obj, name: obj.id == 2 ? 'something' : obj.name}))

You decide what you find most readable…

Since your json is a list of dicts, you can loop through the dicts while checking your required condition:

json = [{
    "id": 1, "name": "a"
}, {
    "id": 2, "name": "b"
}]

for obj in json:
  if obj["id"] == 2:
    obj["name"] = 'something'

Result:

[{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'something'}]

(That's a list of dictionaries, not a JSON string.)

The most concise (you can argue about readability) way I can think of is:

>>> [{**d, 'name': 'something' if d['id'] == 2 else d['name']} for d in json]
[{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'something'}]

This builds a new list of dicts (not an inplace operation), so you would have to reassign the name json.

edit: fixed error from misreading the question.

The syntax in your question is very closed, here are two working versions.

Option 1 use enumerate

If you prefer to access json by index, enumerate is what you are looking for:

for i, x in enumerate(json):
    if x['id'] == 2:
        json[i]['name'] = 'something'

print(json) # what you want

Option 2 directly modify x

From your example, you actually don't need the index i. You can directly modify x to achieve this. The reason is that when iterating a list through for x in, x is a reference to the original item in the list, not a copy, so any modification to x will be reflected in the original list.

for x in json:
    if x['id'] == 2:
        x['name'] = 'something'

print(json) # what you want

Yes, Python has map and friends, see https://docs.python.org/3/library/functions.html .

As others stated, it's more pythonic to just use for loops. But if you want to use (and abuse) functional programming style, you can do it as:

any(map(lambda item: (item['id'] == 2) and item.update(name='something'), json))

The same with some comments:

any( # map will return an iterator, any is there to force the evaluation on each element
    map(
         lambda item:          # function to be applied
             (item['id'] == 2) # our condition
             and               # 'and' is lazy evaluated, if 'id' != 2
                               # we don't evaluate the following line
             item.update(      # update item with another dict
                 name = 'something' # use the fact that keyword arguments are given as a dict
             ), # the return value will always be false
                # forcing 'any' to look further
         json                  # the list we apply the map to
       )
   )

Python have all these functions like map, reduce, and filter. Please refer https://www.learnpython.org/en/Map,_Filter,_Reduce

You also can use the list comprehension feature which is quite useful and handy. Here I have written the list_comprehension for getting the list of specified condition which is id is 2 here.

output_list = [i.get("name") for i in json if i.get("id") == 2]

expected output

['b']
Related