I am trying to create a sequence of similar dictionaries to further store them in a tuple. I tried two approaches, using and not using a for loop
Without for loop
dic0 = {'modo': lambda x: x[0]}
dic1 = {'modo': lambda x: x[1]}
lst = []
lst.append(dic0)
lst.append(dic1)
tup = tuple(lst)
dic0 = tup[0]
dic1 = tup[1]
f0 = dic0['modo']
f1 = dic1['modo']
x = np.array([0,1])
print (f0(x) , f1(x)) # 0 , 1
With a for loop
lst = []
for j in range(0,2):
dic = {}
dic = {'modo': lambda x: x[j]}
lst.insert(j,dic)
tup = tuple(lst)
dic0 = tup[0]
dic1 = tup[1]
f0 = dic0['modo']
f1 = dic1['modo']
x = np.array([0,1])
print (f0(x) , f1(x)) # 1 , 1
I really don't understand why I am getting different results. It seems that the last dictionary I insert overwrite the previous ones, but I don't know why (the append method does not work neither).
Any help would be really welcomed
答案 0 :(得分:1)
这种情况正在发生,因为在这种情况下确定范围如何。尝试将j = 0
置于最终的印刷语句之上,然后您就会看到会发生什么。
另外,您可以尝试
from operator import itemgetter
lst = [{'modo': itemgetter(j)} for j in range(2)]
答案 1 :(得分:0)
你不小心创建了所谓的closure.你的第二个(基于循环的)示例中的lambda函数包括对变量j
的引用。该变量实际上是用于迭代循环的循环变量。因此,lambda
调用实际上生成的代码引用了"一些名为' j'我没有定义,但它在这里的某个地方。"
这称为"关闭"或"封闭"变量j
,因为即使循环结束,你会编写一个引用变量j
的lambda函数。因此,在释放对lambda函数的引用之前,它永远不会被垃圾收集。
你得到相同的值(1,1),因为j
在j = 1时停止迭代range(0,2)
,并且没有任何改变。因此,当你的lambda函数要求x [j]时,他们会要求j
的现值,然后获取{em>当前值 { {1}}。在这两个函数中,j的当前值是1。
您可以通过创建一个以索引号作为参数的x[j]
函数来解决此问题。或者你可以做@DavisYoshida建议的,并使用别人的代码为你创建适当的闭包。