为什么目标数量与预期不同?

时间:2013-11-03 17:55:25

标签: python eclipse python-3.x pydev

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

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

但是,如果我将计数+ = 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,'无效')。

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

3 个答案:

答案 0 :(得分: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))

答案 1 :(得分:0)

...好奇

如果您将“state”更改为其他任何内容,例如State,foo或xyzzy,则它可以正常运行,并且您不会在cacheList中获得“无效”字段。

看起来“state”是枚举内某处的关键字或命名参数,而且某些内容会被破坏。不确定这是否有帮助。

哈努哈利

答案 2 :(得分:0)

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

因此,当您第一次调用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模块,因为它将创建新对象,而不是仅传递引用。