我目前正在执行由ed on edx提供的python入门课程。而且,教授目前正在教授使用函数作为对象。我在其中一个代码中遇到了混淆,他在这个代码中定义了一个函数并且取了两个参数 - 一个是列表而另一个是其他函数。
def applyToEach(l,f):
for i in range(len(l)):
l[i]=f(l[i])
l=[1,-2,3.4]
applyToEach(l,abs)
print(l)
我的问题是:列表中的更改/修改发生在函数内部。那么,它们如何反映在函数之外?据我所知,打印时列表中不应该有任何更改,因为我在函数内部进行了所有更改。我的意思是为不同的功能创建了不同的环境,它只在以前的练习中以这种方式工作,因此更改不会反映在我们的主要环境中。在我错误的地方纠正我,因为当我运行此代码时,修改后的列表将被打印出来。那么,在给定的逻辑中我错了?
答案 0 :(得分:0)
因为它们是相同的对象。您可以通过id()
或is
验证该内容。
#!/usr/bin/env python
#-*- coding:utf-8 -*-
def applyToEach(l,f):
print 'inside id is: ', id(l)
for i in range(len(l)):
l[i]=f(l[i])
l=[1,-2,3.4]
print 'outside id is: ', id(l)
applyToEach(l,abs)
print(l)
在Python中,将值传递给函数等于'para = value'
。但是,'='仅添加对值的引用,但不添加副本。
答案 1 :(得分:0)
该列表作为参数传递给函数。在python中创建列表时,会为其分配一个内存位置以供参考。现在,当您传递列表(或甚至对列表执行任何操作)时,将传递分配的内存位置。因此,无论做了什么修改,都会反映在列表本身中。但内存位置保持不变。因此,无论您是从函数外部还是在函数内部访问它,它都指向相同的内存位置。因此,内部完成的更改在函数外部可见。
让列表为
Fruit = ['Mango', 'Apple', 'Orange']
当我们将列表分配给值Fruit时,会为其分配一个内存位置(此处为4886)
所以id(Fruit) = 4886
现在,假设列表'Fruit'被传递给一个函数,在其中修改它如下: -
def fun(li=[]):
li[1] = 'Grape'
li.extend(['Apple', 'Banana'])
因此,在场景背后发生的事情是,当列表作为参数传递给方法时,实际上,传递列表的引用(或地址)。因此,即使您访问列表并在函数内修改它,它也会在引用列表引用时修改原始列表。因此,列表引用会相应更新。
之后,修改也会显示在方法内部更新的列表。但是,内存位置将是相同的,即id(Fruit) = 4886
即使您将列表分配给新列表i.e. temp = Fruit
,情景也是如此。 temp
将引用与Fruit
相同的位置,列表将指向同一位置。
为避免这种情况,您需要做的是: -
temp = list(Fruit)
将创建一个包含新内存位置的新列表,因此id(Fruit)
将与id(temp)
不同。
以下链接将让您更好地了解列表在python中的工作方式: - http://www.python-course.eu/deep_copy.php