简体   繁体   English

为什么传递数组的副本仍会更改原始数组的值?

[英]Why passing a copy of an array still alters the original array values?

In the main method below, 在下面的main方法中,

1st : I've tried to pass a.copy() and b.copy() as arguments. 1st:我试图传递a.copy()b.copy()作为参数。 Though the solve_linear_equations method returned a valid solution, it still tampers with the original arguments a[][] and b[] . 尽管solve_linear_equations方法返回了有效的解决方案,但仍会篡改原始参数a[][]b[]

2nd : Then, I've tried to define two distinct variables as tmp_a = a.copy() and tmp_b = b.copy() . 2nd:然后,我尝试定义两个不同的变量,分别为tmp_a = a.copy()tmp_b = b.copy() Using these new variables as method parameters did not help either: not always, but usually, the method tampers with the original array values a[][] and b[] . 使用这些新变量作为方法参数也没有帮助:并非总是,但通常,该方法会篡改原始数组值a[][]b[]

I think, there is some kind of a tricky issue concerning Python internals that I couldn't realize. 我认为,关于Python内部结构存在一些棘手的问题,我无法意识到。 Can anybody give a hand? 有人可以帮忙吗?

import random


def data_create(n):
  a, x, b = [], [], []

  for i in range(n):
    a.append([])
    s = random.randint(0, 2)
    x.append(random.randint(0, 1000) / 1000)

    if s:
      x[i] *= -1

    for j in range(n):
      s = random.randint(0, 2)
      a[i].append(random.randint(0, 1000) / 1000)

      if s:
        a[i][j] *= -1

  for i in range(n):
    b.append(0.0)

    for j in range(n):
      b[i] += a[i][j] * x[j]

  return a, x, b


def solve_linear_equations(n, a, x):
  for i in range(n - 1):
    max_row = i
    max_val = abs(a[i][i])

    for j in range(i + 1, n):
      if abs(a[j][i]) > max_val:
        max_val = abs(a[j][i])
        max_row = j

    if max_row != i:
      x[i], x[max_row] = x[max_row], x[i]
      a[i], a[max_row] = a[max_row].copy(), a[i].copy()

    x[i] /= a[i][i]

    for j in range(i + 1, n):
      a[i][j] /= a[i][i]

    a[i][i] = 1.0

    for j in range(i + 1, n):
      x[j] -= x[i] * a[j][i]

      for k in range(i + 1, n):
        a[j][k] -= a[i][k] * a[j][i]

      a[j][i] = 0.0

  x[n - 1] /= a[n - 1][n - 1]
  a[n - 1][n - 1] = 1.0

  for i in range(n - 1, 0, -1):
    for j in range(i - 1, -1, -1):
      x[j] -= x[i] * a[j][i]

      for k in range(i, n):
        a[j][k] -= a[i][k] * a[j][i]

  return x


def main():
  n = 3
  a, x, b = data_create(n)

  print("x\n", x)
  print("a\n", a)
  print("b\n", b, "\n")

  tmp_a = a.copy() # creating a copy of a[][]
  tmp_b = b.copy() # creating a copy of b[]

  print("tmp_a\n", tmp_a)
  print("tmp_b\n", tmp_b, "\n")

  print("x\n", solve_linear_equations(n, tmp_a, tmp_b))
  print("a\n", a)
  print("b\n", b, "\n")


if __name__ == "__main__":
  main()

Instead of 代替

  tmp_a = a.copy() # creating a copy of a[][]
  tmp_b = b.copy() # creating a copy of b[]

do

import copy
...
tmp_a = copy.deepcopy(a) # creating a deep copy of a[][]
tmp_b = copy.deepcopy(b) # creating a deep copy of b[]

This is because list.copy() only goes one level down and you are seeing unwanted changes two levels down. 这是因为list.copy()仅下降了一层,而您看到的不必要的变化则下降了两层。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM