Python 3.x 为什么函数要修改列表?我如何防止它发生?

Python 3.x 为什么函数要修改列表?我如何防止它发生?,python-3.x,Python 3.x,我在Python3.7.x中调用一个函数,并向它传递一个列表。我不想修改列表。在函数内部,我复制列表并修改它 函数完成后,传递给函数的原始列表已被修改。为什么会发生这种情况?我该如何预防 这是密码 def append_string(alist, astring): a_new_list = alist a_new_list.append(astring) return a_new_list my_list = ["a", "b"] my_string = "c" my_

我在Python3.7.x中调用一个函数,并向它传递一个列表。我不想修改列表。在函数内部,我复制列表并修改它

函数完成后,传递给函数的原始列表已被修改。为什么会发生这种情况?我该如何预防

这是密码

def append_string(alist, astring):
    a_new_list = alist
    a_new_list.append(astring)
    return a_new_list
my_list = ["a", "b"]
my_string = "c"
my_new_list = append_string(my_list, my_string)
print(my_list)
print(my_new_list)
这是输出。请注意,
my_list
已被修改

['a', 'b', 'c']
['a', 'b', 'c']


我希望
my_list
保持不变,并且
my_new_list
包含值的串联。

a_new_list=alist
不会复制列表,它只是向同一列表添加一个新名称引用

要复制列表,您可以从几个选项中进行选择

a_new_list=alist[:]
从副本导入副本
新列表=复制(列表)
编辑

写完这篇文章后,我看了看,这里有一个重复的问题:。那里被接受的答案更好、更详细,列出了更多我实际上不知道的选项。

让我试试

在函数中,将列表和对象作为输入。将项目附加到提供的输入后,返回列表

正在发生的是

  • 您正在向函数发送列表的C指针
  • 您可以将一个项目添加到列表中
  • 您正在返回列表的C指针
  • 如您所见,列表的
    id
    只是在函数中进进出出。要获得列表的精确副本,可以使用python内置库中的
    deepcopy
    函数
    copy


    注意:
    id
    函数-返回对象的标识。这保证在同时存在的对象中是唯一的。

    您应该注意,使用
    copy
    创建浅拷贝。对于一维数字列表,这不是问题。但是,如果你有一个列表,这将是一个问题。例:
    a=[0];b=[a];c=副本(b)
    。然后
    c为b
    返回False(如预期的那样),但
    c[0]为b[0]
    返回True-->不复制内部列表。如果这是一个问题,请改用
    copy.deepcopy
    
    >>> def append_string(alist, astring):
    ...     a_new_list = alist
    ...     a_new_list.append(astring)
    ...     print(id(a_new_list)) # print the list's id
    ...     return a_new_list
    ...
    >>>
    >>> alist = ['a', 'b', 'c']
    >>> id(alist)
    140215330632840
    >>>
    >>> 
    >>> append_string(alist, 'd') # this 
    140215330632840
    ['a', 'b', 'c', 'd']
    >>>
    >>> id(append_string(alist, 'd'))
    140215330632840
    140215330632840
    >>>