Sequence of dictionaries in python

时间:2016-02-03 04:17:17

标签: list python-3.x dictionary tuples

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

2 个答案:

答案 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建议的,并使用别人的代码为你创建适当的闭包。