关于python:List append会覆盖我之前的值

List append is overwriting my previous values

本问题已经有最佳答案,请猛点这里访问。

我正在尝试为ElasticSearch动态构建一个查询,下面是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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))

我期待这样的输出:

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

但是我得到的是:

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

注意labels.Name中的重复值。

当我在列表中追加时出现问题,这将覆盖上一个值。


问题不在列表中,而是在词典中:您更新了

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

在for循环的每个迭代中。你可以替换

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

比如:

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

你每次都在把同一本词典添加到你的列表中。这本词典仅供参考。您可以通过每次构造新字典来引用新字典:

1
2
3
4
5
6
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,嵌套。


python字典是通过引用传递的。这意味着,当您附加到must_string时,您实际上附加了对term_string字典的引用,因此当您在下面的循环中修改术语"字符串字典"时,它会更改基础字典,而不仅仅是最新版本。

要想做你想做的事情,你需要为每个要附加的循环制作一个新的字典,或者你可以在附加之前(从copy库)创建一个你的字典的deepcopy()