【问题标题】:Python append acting funny [duplicate]Python附加行为有趣[重复]
【发布时间】:2019-08-23 09:08:21
【问题描述】:

我写了一个python代码来解决一个难题。它没有按预期工作。所以在调试时我看到了一些非常奇怪的东西。行是列表的列表。将 1 附加到单个 row[n] 附加到行内的所有列表!

def trap( height):
        row = []

        for index, i in enumerate(height):
            if i == 0 and len(row) == 0:
                continue
            else:
                if(i > len(row)):#time for a new row
                  #to old rows append 0 below  
                  for j in range(0, len(row)):
                        row[j].append(0)
                  row = row + [[0]] * (i - len(row))            
                else:
                  for j in range(0,i):
                     row[j].append(0)
                  #PROBLEMATIC CODE START  
                  for jo in range(i,len(row)):
                        if(index == 1):
                            print("jays are",row)
                            print("jo is",jo, row[jo])
                        row[jo].append(1)
                  #PROBLEMATIC CODE END (I GUESS?)


        print(row) #print this, it gives an idea


trap([2,0])

当我独立尝试时,它工作正常,请参阅:

row = [[0],[0]]
index = 1

for jo in range(0,len(row)):
      if(index == 1):
                  print("jays are",row)
                  print("jo is",jo, row[jo])
                  row[jo].append(1)
print(row)

有问题的代码已在 python 中标记为注释#PROBLEMATIC CODE START#PROBLEMATIC CODE END。用[2,0]拨打trap()

行变量应该是[[0,1],[0,1]] 但行变量即将到来[[0,1,1],[0,1,1]]

我已经在这里待了好几个小时了!我只是不明白为什么.append() 会附加到行内的所有列表中,但是当我尝试使用较小的代码时它可以工作。请帮助我并指导我

【问题讨论】:

  • 问题在于您编辑该行的方式。 row = row + [[0]] * (i - len(row)) 当使用带有列表的“*”运算符时,同一个对象会被沿行多次引用。跨度>
  • 很确定list.append 工作正常,您的代码只是混乱:) 您可能会发现我的general tips on debugging small Python programs 很有帮助。一般来说,从正在运行的代码开始,一次一点地构建它,确保每一步都按预期工作,而不是尝试一次完成所有事情。

标签: python python-3.x


【解决方案1】:

使用* 创建列表时,您只是复制对对象的引用,而不是实例本身。简短的例子:

>>> a = [["abv"]] * 3
>>> a
[['abv'], ['abv'], ['abv']]
>>> a[0].append(1)
>>> a
[['abv', 1], ['abv', 1], ['abv', 1]]

我正在创建一个包含对象["abv"] 3 次的列表。都是同一个对象,列表中只有 3 次。 一旦我编辑了一个项目,看起来所有项目都更新了,但实际上都是一样的。

您需要像这样创建列表,以便为每次迭代创建一个新对象:

>>> a = [["abv"] for _ in range(3)]

所以你的代码应该改成这样:

row += [[0] for x in range(i - len(row))]

【讨论】:

    【解决方案2】:

    要回答这个问题,您需要稍微修改一下代码。

    #to old rows append 0 below  
    for j in range(0, len(row)):
        row[j].append(0)
    row = row + [[0]] * (i - len(row))
    

    您需要修改它以删除同一对象上的多个引用。

    #to old rows append 0 below  
    for j in range(0, len(row)):
        row[j].append(0)
    row += [[0] for x in range(i - len(row))]
    

    有了这个,你可能应该得到正确的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 2016-06-20
      • 1970-01-01
      • 2019-03-16
      • 2017-02-16
      相关资源
      最近更新 更多