DefaultDict 在这两种情况下的行为不同
DefaultDict behaves differently in both cases
我有以下内容:
a = [{ "_id" : { "reportId" : "5a27cda63fff647c33a14b31" }, "amount" : 3000 },
{ "_id" : { "reportId" : "5a27cda63fff647c33a14b31", "name" : "sriram sathyan" }, "amount" : 0 },
{ "_id" : { "reportId" : "5a27cf173f978655f2efbee7" }, "amount" : 1200 },
{ "_id" : { "reportId" : "5a27cf173f978655f2efbee7", "name" : "karthik subbaraj" }, "amount" : 0 }
]
我想要以下结构:
{'reportid1':{'name':'sriram sathyan','amount':3000}, .....}
我尝试了以下代码:
names = defaultdict(dict)
for item in a:
report_id = item['_id']['reportId']
amount = item['amount']
names[report_id] = {'name': item['_id'].get('name','')}
if amount != 0:
names[report_id].update({'amount': amount})
print(dict(names))
输出:
{'5a27cda63fff647c33a14b31': {'name': 'sriram sathyan'}, '5a27cf173f978655f2efbee7': {'name': 'karthik subbaraj'}}
(不是我想要的)
然后我把上面的代码改成了:
for item in a:
report_id = item['_id']['reportId']
amount = item['amount']
if amount != 0:
names[report_id] = {'amount': amount}
names[report_id].update({'name': item['_id'].get('name','')})
print(dict(names))
这输出:
{'5a27cda63fff647c33a14b31': {'amount': 3000, 'name': 'sriram sathyan'}, '5a27cf173f978655f2efbee7': {'amount': 1200, 'name': 'karthik subbaraj'}}
(我想要的!!!!!!)
所以问题是=>
if 语句的放置怎么会导致这样的变化呢?还是我在这里缺少什么?
问题是您有相同的键,一个 amount
在数据中等于零,另一个 amount
不 零。
在第一个循环中,首先创建具有非零值 amount
的条目,然后被具有零值的条目覆盖 amount
所以两个代码都会覆盖一些条目,但是第一个代码会覆盖您想要保留的条目,而第二个代码(有效的代码)会用零 amount
.
覆盖条目
问题是,在第一种情况下,您在这一行 覆盖了 names[report_id]
:
names[report_id] = {'name': item['_id'].get('name','')}
让我们关注 names
词典中的 5a27cda63fff647c33a14b31
项:
在循环的第一次迭代中,您正在设置 names[report_id]
:
的值
{'5a27cda63fff647c33a14b31': {'name': ''}}
那么,由于金额为3000,字典更新为:
{'5a27cda63fff647c33a14b31': {'name': '', 'amount': 3000}}
然后,在循环的第二次迭代中,字典被完全覆盖,导致 amount
值完全丢失:
{'5a27cda63fff647c33a14b31': {'name': 'sriram sathyan'}}
使用调试器逐行跟踪执行,观察names
字典如何变化。
我有以下内容:
a = [{ "_id" : { "reportId" : "5a27cda63fff647c33a14b31" }, "amount" : 3000 },
{ "_id" : { "reportId" : "5a27cda63fff647c33a14b31", "name" : "sriram sathyan" }, "amount" : 0 },
{ "_id" : { "reportId" : "5a27cf173f978655f2efbee7" }, "amount" : 1200 },
{ "_id" : { "reportId" : "5a27cf173f978655f2efbee7", "name" : "karthik subbaraj" }, "amount" : 0 }
]
我想要以下结构:
{'reportid1':{'name':'sriram sathyan','amount':3000}, .....}
我尝试了以下代码:
names = defaultdict(dict)
for item in a:
report_id = item['_id']['reportId']
amount = item['amount']
names[report_id] = {'name': item['_id'].get('name','')}
if amount != 0:
names[report_id].update({'amount': amount})
print(dict(names))
输出:
{'5a27cda63fff647c33a14b31': {'name': 'sriram sathyan'}, '5a27cf173f978655f2efbee7': {'name': 'karthik subbaraj'}}
(不是我想要的)
然后我把上面的代码改成了:
for item in a:
report_id = item['_id']['reportId']
amount = item['amount']
if amount != 0:
names[report_id] = {'amount': amount}
names[report_id].update({'name': item['_id'].get('name','')})
print(dict(names))
这输出:
{'5a27cda63fff647c33a14b31': {'amount': 3000, 'name': 'sriram sathyan'}, '5a27cf173f978655f2efbee7': {'amount': 1200, 'name': 'karthik subbaraj'}}
(我想要的!!!!!!)
所以问题是=> if 语句的放置怎么会导致这样的变化呢?还是我在这里缺少什么?
问题是您有相同的键,一个 amount
在数据中等于零,另一个 amount
不 零。
在第一个循环中,首先创建具有非零值 amount
的条目,然后被具有零值的条目覆盖 amount
所以两个代码都会覆盖一些条目,但是第一个代码会覆盖您想要保留的条目,而第二个代码(有效的代码)会用零 amount
.
问题是,在第一种情况下,您在这一行 覆盖了 names[report_id]
:
names[report_id] = {'name': item['_id'].get('name','')}
让我们关注 names
词典中的 5a27cda63fff647c33a14b31
项:
在循环的第一次迭代中,您正在设置
的值names[report_id]
:{'5a27cda63fff647c33a14b31': {'name': ''}}
那么,由于金额为3000,字典更新为:
{'5a27cda63fff647c33a14b31': {'name': '', 'amount': 3000}}
然后,在循环的第二次迭代中,字典被完全覆盖,导致
amount
值完全丢失:{'5a27cda63fff647c33a14b31': {'name': 'sriram sathyan'}}
使用调试器逐行跟踪执行,观察names
字典如何变化。