如果我将数据帧传递给函数并在函数内部对其进行修改,那么它是按值传递还是按引用传递?
我运行以下代码
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
def letgo(df):
df = df.drop('b',axis=1)
letgo(a)
a
函数调用后,的值不变。这是否意味着价值传递?
我也尝试了以下
xx = np.array([[1,2], [3,4]])
def letgo2(x):
x[1,1] = 100
def letgo3(x):
x = np.array([[3,3],[3,3]])
事实证明letgo2()
,变化xx
并letgo3()
没有。为什么会这样呢?
简短的答案是,Python始终会传递值,但每个Python变量实际上都是指向某个对象的指针,因此有时看起来像是传递引用。
在Python中,每个对象都是可变的或不可更改的。例如,列表,字典,模块和熊猫数据帧是可变的,而整数,字符串和元组是不可变的。可变对象可以在内部进行更改(例如,将元素添加到列表中),但非可变对象则不能。
正如我在开始时所说的,您可以将每个Python变量都视为指向对象的指针。当您将变量传递给函数时,函数中的变量(指针)始终是传入的变量(指针)的副本。因此,如果将新内容分配给内部变量,则您所做的就是更改局部变量指向另一个对象。这不会更改(变异)变量指向的原始对象,也不会使外部变量指向新对象。此时,外部变量仍指向原始对象,但内部变量指向新对象。
如果要更改原始对象(仅适用于可变数据类型),则必须执行一些更改对象的操作, 而无需
为局部变量分配全新的值。这就是为什么letgo()
和letgo3()
离开外部项目不变,但letgo2()
会改变它。
正如@ursan指出的那样,如果letgo()
使用类似这样的东西,那么它将改变(变异)df
指向的原始对象,这将改变通过全局a
变量看到的值:
def letgo(df):
df.drop('b', axis=1, inplace=True)
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
letgo(a) # will alter a
在某些情况下,您可以完全掏空原始变量,并用新数据重新填充它,而无需实际进行直接分配,例如,这将更改v
指向的原始对象,这将更改v
以后使用的数据:
def letgo3(x):
x[:] = np.array([[3,3],[3,3]])
v = np.empty((2, 2))
letgo3(v) # will alter v
注意,我不是直接分配东西给x
;。我正在为的整个内部范围分配内容x
。
如果您绝对必须创建一个全新的对象并使其在外部可见(大熊猫有时就是这种情况),则有两个选择。“干净”选项只是返回新对象,例如,
def letgo(df):
df = df.drop('b',axis=1)
return df
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
a = letgo(a)
另一种选择是到达函数外部并直接更改全局变量。这将更a
改为指向一个新对象,a
此后引用的任何函数都将看到该新对象:
def letgo():
global a
a = a.drop('b',axis=1)
a = pd.DataFrame({'a':[1,2], 'b':[3,4]})
letgo() # will alter a!
直接更改全局变量通常不是一个好主意,因为任何读取您的代码的人都将很难找出a
更改的方式。(我通常将全局变量用于脚本中许多函数使用的共享参数,但我不允许它们更改那些全局变量。)
本文向大家介绍JS是按值传递还是按引用传递,包括了JS是按值传递还是按引用传递的使用技巧和注意事项,需要的朋友参考一下 按值传递 VS. 按引用传递 按值传递(call by value)是最常用的求值策略:函数的形参是被调用时所传实参的副本。修改形参的值并不会影响实参。 按引用传递(call by reference)时,函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值如果被
问题内容: 我一直认为Java使用传递引用。 但是,我已经看到了几篇博客文章声称不是(博客文章说Java使用值传递)。 我不认为我能理解他们的区别。 有什么解释? 问题答案: Java总是按值传递。 不幸的是,我们根本不处理任何对象,而是处理称为引用的 对象句柄(当然是通过值传递)。选择的术语和语义很容易使许多初学者感到困惑。 它是这样的: 在上面的示例中仍将返回”Max”。值aDog内main未
问题内容: 基本类型(数字,字符串等)按值传递,但对象未知,因为它们都可以按值传递(如果我们认为保存对象的变量实际上是对该对象的引用) )和按引用传递(当我们认为对象的变量包含对象本身时)。 尽管最后并没有什么大不了,但我想知道呈现通过惯例的参数的正确方法是什么。是否有JavaScript规范的摘录,其中定义了与此相关的语义? 问题答案: JavaScript很有趣。考虑以下示例: 产生输出: 如
问题内容: 我读了许多文章,都说Java是通过价值传递的。但是我仍然不能解释按值传递和引用之间的区别。我写了一个示例程序,它像这样执行。 执行 谁能向我解释这些问题… 价值传递是什么意思? 答:它只是将存储在变量中的数字或值传递给函数。我是对还是错。 How do you say Java是通过价值传递? 为什么Java是按值传递而不是按引用传递? 上面的程序Tries是否显示了“按值传递”和“引
我创建了一个MapReduce作业,该作业将计算键的数量,然后根据它们出现的次数对它们进行排序 处理输入时,如 最终目标将是一个类似于 我的地图阶段输出a 我的减少阶段有3个阶段:设置,我初始化一个数组列表来保存我的 数组列表中的值是我创建的一个对象myObject的值,它将文本和Int保存在一个元组中可写,我发现一个奇怪的地方是当我这样做的时候 key是传递到reducer的键,count是我通
问题内容: PHP变量是通过值还是通过引用传递? 问题答案: 根据PHP文档的价值。 默认情况下,函数参数是按值传递的(因此,如果函数中参数的值发生更改,则不会在函数外部进行更改)。要允许函数修改其参数,必须通过引用将其传递。 有一个参数总是通过引用传递函数,在前面加上符号( & ),以在函数定义的参数名称。