обновить значение свойства json, используя для l oop in python? - PullRequest
1 голос
/ 19 июня 2020

Есть ли в python util l oop как в javascript? (например, сопоставить, уменьшить и отфильтровать). Или все должно быть сделано вручную, используя для l oop?

У меня есть простые 2 записи объекта, как показано ниже

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

Как я могу обновить свойство name, если id равно 2?

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

Ответы [ 6 ]

2 голосов
/ 19 июня 2020

Прямой способ:

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

Объекты изменяемы, поэтому вы здесь напрямую мутируете объект. Это самый простой способ. Типичный эквивалент Javascript будет выглядеть следующим образом:

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

Немного более сжатая версия:

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

Это встраивает выражение генератора, которое предварительно фильтрует объекты до l oop более. В качестве альтернативы:

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

В некоторой степени эквивалентно:

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

Еще более сжатая версия:

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

Это понимание списка, которое создает новый объект и новый список, что-то вроде:

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

Вы сами решаете, что вы считаете наиболее читаемым…

2 голосов
/ 19 июня 2020

Так как ваш json является списком dicts, вы можете l oop через dicts, проверяя необходимое условие:

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

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

Результат:

[{'id': 1, 'name': 'a'}, {'id': 2, 'name': 'something'}]
1 голос
/ 19 июня 2020

(Это список словарей, а не строка JSON.)

Самый лаконичный (вы можете спорить о удобочитаемости) способ, который я могу придумать:

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

Это создает новый список dicts (не операция на месте), поэтому вам придется переназначить имя json.

edit : исправлена ​​ошибка из-за неправильного прочтения вопроса.

0 голосов
/ 19 июня 2020

Да, Python имеет map и друзей, см. https://docs.python.org/3/library/functions.html.

Как утверждали другие, pythoni c просто использовать для циклов. Но если вы хотите использовать (и злоупотреблять) стилем функционального программирования, вы можете сделать это как:

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

То же самое с некоторыми комментариями:

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
       )
   )
0 голосов
/ 19 июня 2020

Синтаксис в вашем вопросе очень закрытый, вот две рабочие версии.

Вариант 1 используйте enumerate

Если вы предпочитаете получить доступ к json через index, enumerate это то, что вы ищете:

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

print(json) # what you want

Вариант 2 напрямую изменить x

В вашем примере вам действительно не нужен индекс i. Для этого вы можете напрямую изменить x. Причина в том, что при итерации списка через for x in, x является ссылкой на исходный элемент в списке, а не копией, поэтому любые изменения x будут отражены в исходном списке.

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

print(json) # what you want
0 голосов
/ 19 июня 2020

Python имеют все эти функции, такие как отображение, сокращение и фильтр. См. https://www.learnpython.org/en/Map, _ Filter, _Reduce

Вы также можете использовать функцию понимания списка, которая очень полезна и удобна. Здесь я написал list_comprehension для получения списка указанного условия, который здесь id равен 2.

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

ожидаемый результат

['b']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...