0

以下是我的代码,我打算计算一个列表被修改了多少次,但是计数似乎是错误的,我的代码如下所示:

t=(0,999999,"state")

cachLine = []

for x in range(0,2):
    cachLine.append(t);

cache = []
for x in range(0,1):
    cache.append(cachLine)

cacheList = []

for x in range(0,8):
    cacheList.append(cache)

count=0

for cacheI,cache in enumerate(cacheList):
    for clI,cl in enumerate(cache):
        for bI,(valid, address, state) in enumerate(cl):

            if state =='state': 
                cacheList[cacheI][clI][bI] = (valid, address,'invalid')
                count +=1
print(count)

在这种情况下计数为2,与预期的不一样,应该是16

但是,如果我将 count+=1 的顺序更改为

for cacheI,cache in enumerate(cacheList):
    for clI,cl in enumerate(cache):
        for bI,(valid, address, state) in enumerate(cl):
            count +=1    
            if state =='state': 
                cacheList[cacheI][clI][bI] = (valid, address,'invalid')

print(count)

我得到了 16 的正确计数。在这两种情况中的任何一种情况下,我都会得到 cacheList 的输出:

[[[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]], [[(0, 999999, 'invalid'), (0, 999999, 'invalid')]]]

这是 16 个元组 (0, 999999, 'invalid')。

第一个代码中的计数有什么问题?

4

3 回答 3

1

您应该在添加列表之前复制它们:

import copy

cache = []
for x in range(0,1):
    cache.append(copy.deepcopy(cachLine))

cacheList = []

for x in range(0,8):
    cacheList.append(copy.deepcopy(cache))
于 2013-11-03T18:05:45.487 回答
0

在您的代码中,您附加了 8 次 SAME 缓存,其中包含 SAME 缓存行。您的 cacheList 最终包含一堆对完全相同的对象的引用:两个元组的列表

所以第一次调用时cacheList[cacheI][clI][bI] = (valid, address,'invalid'),你修改了这个公共对象。count = 1,每个缓存线现在是:

[(0,999999,"state"), (0,999999,"invalid")]

第二次之后,count = 2,cacheline 为:

[(0,999999,"invalid"), (0,999999,"invalid")]

在你的内循环第一次完成后,每个“状态”都变成了“无效”。因此,您的计数停止在 2。

解决方案确实是使用copy模块,因为它将创建新对象,而不仅仅是传递引用。

于 2013-11-04T14:38:24.947 回答
0

好奇的...

如果您将“状态”更改为其他任何内容,例如 State、foo 或 xyzzy,它会起作用,并且您不会在 cacheList 中获得“无效”字段。

看起来“状态”是枚举内部某处的关键字或命名参数,并且某些东西被破坏了。不确定这是否有帮助。

汉努

于 2013-11-03T18:24:12.527 回答