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)
使用最后一个“闭包值”