Python 为什么我会在这个生成器中得到一个键错误?
我有以下字典:Python 为什么我会在这个生成器中得到一个键错误?,python,dictionary,generator,Python,Dictionary,Generator,我有以下字典: d={ “A”:{ “param”:{ '1': { 'req':True, }, '2': { 'req':True, }, }, }, “B”:{ “param”:{ '3': { 'req':True, }, '4': { 'req':False, }, }, }, } 我想有一个发电机,它会给我的每一个第一级的关键,所需的参数 req={} 对于输入d: req[key]=(如果d[key]['param'][p],则d[key]['param'][p]中p代表p。ge
d={
“A”:{
“param”:{
'1': {
'req':True,
},
'2': {
'req':True,
},
},
},
“B”:{
“param”:{
'3': {
'req':True,
},
'4': {
'req':False,
},
},
},
}
我想有一个发电机,它会给我的每一个第一级的关键,所需的参数
req={}
对于输入d:
req[key]=(如果d[key]['param'][p],则d[key]['param'][p]中p代表p。get('req',False))
所以在这里,对于d
中的每个键,只有当req
为True
时,我才能得到参数p
但是,当我尝试使用生成器时,它会引发一个KeyError
异常:
>>请求
{'A':,
‘B’:}
>>>对于req['A']中的元素:
... 打印元素
---------------------------------------------------------------------------
KeyError回溯(最近一次呼叫最后一次)
在()
---->1对于req['A']中的元素:
2打印元素
3.
在((p,))
1对于d键:
---->2 req[key]=(如果d[key]['param'][p],则p代表d[key]['param']中的p。get('req',False))
3.
KeyError:“1”
分配给req[key]
的生成器表达式绑定在key
变量上。但是键
在循环中从“A”变为“B”。当您迭代第一个生成器表达式时,它将在其if
条件下将key
计算为'B',即使创建它时key
是'A'
绑定到变量值而不是其引用的传统方法是使用默认值将表达式包装在lambda中,然后立即调用它
for key in d:
req[key] = (lambda key=key: (p for p in d[key]['param'] if d[key]['param'][p].get('req', False)))()
结果:
1
2
这是因为在执行生成器时,会使用
键的最新值
假设d中键的:
按'A',B'
的顺序迭代键,第一个生成器应该使用键='A'
,但由于闭包问题,它使用'B'
的项作为键。并且它没有'1'
子条目
更糟糕的是,生成器中的key
变量有两个不同的值:d[key]['param']
部分中p的使用“正确”值,而if d[key]['param'][p].get('req',False)
使用最后一个“闭包值”