Python deque scope?

2024-03-29 10:30:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习Python并且一直在努力做一个deque。但是,我得到了错误的输出,我不知道为什么。我的代码如下:

p = [2, 1], [1, 1]
init_q= deque()

init_q.append(p)
for i in range(len(p)):
    for j in range(len(p[i])):
        temp = p[i][j]
        p[i][j] = 0
        init_q.append(p)
        p[i][j] = temp

while init_q:
    print init_q.pop()

在这段代码中,我接受一个列表,然后我想创建一个包含5个列表的队列,其中4个在不同的位置有一个0,我想要的结果是:

^{pr2}$

然而,我得到的结果是:

([2, 1], [1, 1])
([2, 1], [1, 1])
([2, 1], [1, 1])
([2, 1], [1, 1])
([2, 1], [1, 1])

Tags: 代码in列表forlen队列init错误
3条回答

根据我对Ned Batchelder的回答的评论,下面是你如何做到一成不变:

for i in range(len(p)):
    for j in range(len(p[i])):
        temprow = [0 if y==j else p[i][y] for y in range(len(p[i]))]
        temp = [temprow if x==i else p[x] for x in range(len(p))]
        init_q.append(temp)

在这种情况下,我认为结果比他的建议可读性差得多:

^{pr2}$

就像我说的,有时候它会让事情变得简单,有时候会让事情变得不那么简单……但关键是它更容易推理。您不必担心init_q中的多个list,或者更糟的是,这些list中的子list是否共享身份。在

权衡是否值得,这实际上是一个具体情况的决定,可能每个程序员都不同。在这种情况下,我不会使用不可变的解决方案,而且我怀疑许多其他(Python)程序员会这样做。但知道怎么写是值得的。在

您还可以考虑将其作为3D列表而不是2D列表的deque,然后将其输入deque。这显然是等价的,但从概念上来说,这样想可能更简单:

init_q.append(p)
q = [copy.deepcopy(p) for i in range(len(p)) for j in range(len(p[i]))]
for i in range(len(p)):
    for j in range(len(p[i])):
        q[i*len(p[i])+j][i][j] = 0
init_q.extend(q)

PS,如果你做了很多这样的事情,你可以看看^{}。如果这就是你的全部问题,对你没有任何好处…但是如果你用多维数组做更复杂的事情,它会的。在

我通过简化代码创建了一个关于Python的visualization教程。摆弄一下,你就能很容易地看到发生了什么。在

只需对代码进行一行更改就可以解决此问题。在

init_q.append(map(list, p))    # Initialize a new list from p's element lists

这是使用上述更改的visualization。在

你把一个对象放入deque,然后改变这个对象。事实上,您总是将同一个对象放入deque中,因此deque中的所有对象都是对一个对象p的引用

相关问题 更多 >