循环迭代器的意外行为

2024-05-08 01:41:25 发布

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

我有两个结构非常相似的函数。第一种方法创建一个dict的3D列表并添加数据(数据由用于构建列表的三个迭代器的值组成)。第二个简单地显示dict数据。问题是第二个函数显示的数据错误。而不是显示迭代器的值按预期增加:

(0, 9, 19)
(0, 9, 20)
(0, 10, 0)
(0, 10, 1)
(0, 10, 2)

最后显示迭代器的最大值:

(0, 12, 20)
(0, 12, 20)
(0, 12, 20)
(0, 12, 20)
(0, 12, 20)

代码如下:

xCount = 13
yCount = 21
numPages = 1
skip = [[4, 7], [4, 13], [8, 7], [8, 13]]

def createFrames():
  frameData = {'textFrameName': ''}
  framesData = [[[frameData for y in range(yCount)] for x in range(xCount)] for p in range(numPages)]

  for p in range(numPages):
    for x in range(xCount):
      for y in range(yCount):

        skipFrame = False

        for entry in skip:
          if entry[0] == x and entry[1] == y:
            skipFrame = True

        if skipFrame == False:
          framesData[p][x][y]['textFrameName'] = str(p) + ', ' + str(x) + ', ' + str(y)
          print(framesData[p][x][y]['textFrameName']) # shows p, x, y incrementing

  return framesData

def displayData(framesData):
  for p in range(numPages):
    for x in range(xCount):
      for y in range(yCount):

        skipFrame = False

        for entry in skip:
          if entry[0] == x and entry[1] == y:
            skipFrame = True

        if skipFrame == False:
          print(framesData[p][x][y]['textFrameName']) # shows 0, 12, 20 only


# Create text frames.
framesData = createFrames()

# Add data to dictionaries.
displayData(framesData)

使用python 2.7.16


1条回答
网友
1楼 · 发布于 2024-05-08 01:41:25

问题来自于对列表的理解。您使用的frameData是可变的,因此每次更新它时,您都会到处更新它

以下是显示相同行为的简化流程:

>>> a = {"a" : 1}
>>> l = [a for _ in range(3)]
>>> l
[{'a': 1}, {'a': 1}, {'a': 1}]
>>> l[0]["a"] = 2
>>> l
[{'a': 2}, {'a': 2}, {'a': 2}] 

您可以使用.copy()创建一个副本,或者每次在文档中创建对象

>>> a = {"a" : 1}
>>> l2 = [a.copy() for _ in range(3)]
>>> l2[0]["a"] = 2
>>> l2
[{'a': 2}, {'a': 1}, {'a': 1}]
>>> # or
>>> l3 = [{"a" : 1} for _ in range(3)]
>>> l3[0]["a"] = 2
>>> l3
[{'a': 2}, {'a': 1}, {'a': 1}]

相关问题 更多 >