Список добавления перезаписывает мои предыдущие значения [дубликаты]

1

Я пытаюсь динамически построить запрос для ElasticSearch, вот мой код:

import json

query_string = "person human"

query = {}

query['query'] = {}
query['query']['bool']  = {}
query['query']['bool']['must']  = {}

must_string = []
term_string = {}
term_string['term'] = {}
term_string['term']["labels.Name"] = ""

for term in query_string.split():
    term_string['term']["labels.Name"] = term
    must_string.append(term_string)

query['query']['bool']['must'] = must_string

print(json.dumps(query))

Я ожидал вывод, как это:

{"query": {"bool": {"must": [{"term": {"labels.Name": "person"}}, {"term": {"labels.Name": "human"}}]}}}

но вместо этого я получаю это:

{"query": {"bool": {"must": [{"term": {"labels.Name": "human"}}, {"term": {"labels.Name": "human"}}]}}}

Обратите внимание на дублированное значение в labels.Name. labels.Name.

Существует проблема, когда я добавляю в список и перезаписываю предыдущее значение.

Теги:

3 ответа

1

Вы добавляете один и тот же словарь в свой список каждый раз. Ссылка на один словарь. Вы можете ссылаться на новый словарь, создавая новый словарь каждый раз:

for term in query_string.split(): 
    term_string = {}
    term_string['term'] = {}
    term_string['term']["labels.Name"] = ""
    term_string['term']["labels.Name"] = term
    must_string.append(term_string)

Для построения вложенного словаря я рекомендую вам использовать collections.defaultdict: см. Defaultdict defaultdict, вложенный.

  • 0
    Таким образом, используя collection.defaultdict, можно будет напрямую присваивать значения без инициализации переменных?
  • 0
    @ user1297406, именно так. Смотрите ссылку в моем ответе для примера.
Показать ещё 1 комментарий
1

Проблема заключается не в списке, а в словаре: вы обновляете значение

term_string['term']["labels.Name"]

на каждой итерации цикла for. Вы можете заменить

term_string['term']["labels.Name"] = term

что-то вроде:

term_string = {'term':{'labels.name':term}}
0

Словарь Python передается по ссылке. Это означает, что при добавлении к must_string вы действительно добавляете ссылку на словарь term_string, так что, когда вы изменяете словарь term_string в следующем цикле, он меняет основной словарь, а не только последнюю версию.

Чтобы сделать то, что вы хотите, вам нужно будет создать новый словарь для каждого цикла для добавления, или вы можете сделать deepcopy() (из библиотеки copy) вашего словаря, прежде чем добавлять его.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню