python在函数中更改外部变量值

目录

前言

列表、字典(可变对象)

元组(不可变对象)

全局变量


前言

今天在写LeetCode题时,发现一个问题我并没有掌握,那就是如何在Python的函数中更改变量值(包括列表,字典,元组,数值等),经过搜集资料与自己验证,我渐渐明白这个知识点。

这里说的是改变变量的值,如果仅是需要变量改变后的值,只需 return 所需值即可。


列表、字典(可变对象)

对于可变对象(如列表、字典)的参数传递,是传递的对象的引用。在函数中引用后,用下标(字典是键值)访问或利用append()等函数进行修改,是可以在函数外体现出改变的

如:

列表:

def modify_list(lst):
    lst[0] = 100  # 修改列表的第一个元素
    lst.append(200)  # 在列表末尾添加一个新元素
    lst.extend([1,2,3])#末尾添加三个数
    del lst[-1]#末尾删除一个数
    lst.pop()#末尾删除一个数
    lst.insert(1,66)#插入一个数

# 声明一个列表
my_list = [1, 2, 3]

print("修改前:", my_list)
modify_list(my_list)
print("修改后:", my_list)

字典: 

def modify_dict(dic):
    dic[1]=25   # 修改键值为1的内容
    dic['o']='my'#增加键值
    del dic[0]#删除键值

#声明一个字典
my_dict={1:"ok",0:56}
print("修改之前",my_dict)
modify_dict(my_dict)
print("修改之后",my_dict)

但之后我遇到一个问题,原代码是:

class Solution(object):
    def removeDuplicates(self, nums):
        s=set(nums)
        nums=list(s)
        return len(nums)
A=Solution()
nums=[1,1,2,3,4,4]
k=A.removeDuplicates(nums)
print(k,nums)

 

在这段代码中,nums的内容并没有被改变,这是为什么呢?

经过搜集资料与思考,我找到了原因:

在这段代码中,nums列表虽然被传递给函数 removeDuplicates,并在函数中对 nums 进行了修改操作,但是这里需要注意的是,对于可变对象(如列表)的参数传递,是传递的对象的引用。

在函数内部执行 nums=list(s) 时,实际上创建了一个新的列表,并将该列表的引用赋值给了局部变量 nums。因此,对 nums 的修改只会影响到函数内部的局部变量,在函数结束后,这个局部变量将会被销毁,原始的 nums 列表并没有改变。

如果希望在函数中修改原始列表,可以直接使用切片操作,将集合 s 中的元素更新到原始列表中,示例如下:

class Solution(object):
    def removeDuplicates(self, nums):
        s=set(nums)
        nums[:]=list(s)
        return len(nums)
A=Solution()
nums=[1,1,2,3,4,4]
k=A.removeDuplicates(nums)
print(k,nums)

在这个示例中,通过使用切片操作 nums[:] = list(s),将集合 s 转换成列表,并直接更新到原始列表 nums 中。这样就可以修改原始列表的值,并且在函数结束后,原始列表的值也被相应地更改了。

两段代码的结果分别是:

 为了更好地说明,我输出了二者的ID:
 

def func1( nums):
        s=set(nums)
        nums=list(s)
        print("函数1中:",id(nums))
        return len(nums)
def func2( nums):
        s=set(nums)
        nums[:]=list(s)
        print("函数2中:",id(nums))
        return len(nums)
nums=[1,1,2,3,4,4]
print("函数外",id(nums))
k=func1(nums)
k=func2(nums)
print("函数外",id(nums))

# 结果:
#     函数外 2340821850560
#     函数1中: 2340825133376
#     函数2中: 2340821850560
#     函数外 2340821850560

可以看出,在 函数func1 中的ID与其他都不同,意味着创建了一个新的局部变量列表。当然,如果仅是需要该值,return 即可。


元组(不可变对象)

在Python中,元组(tuple)是不可变对象,即元组的值不能被修改。因此,无法直接在函数中修改元组的值。

当你将一个元组作为参数传递给函数时,实际上是将元组的引用传递给了函数。函数内部可以访问元组的值,但无法对其进行修改。

如果你需要在函数中修改元组的值,一种常见的方法是将元组转换为可变对象(如列表),在函数内部对可变对象进行修改后,再将其转换回元组。

以下是一个示例代码,展示了如何通过转换为列表来修改元组的值:

def modify_tuple(t):
    lst = list(t)  # 将元组转换为列表
    lst[0] = 100  # 修改列表的第一个元素
    # 进行其他操作...
    modified_tuple = tuple(lst)  # 将列表转换回元组
    return modified_tuple

# 声明一个元组
my_tuple = (1, 2, 3)

print("修改前:", my_tuple)
modified_tuple = modify_tuple(my_tuple)
print("修改后:", modified_tuple)

结果:

修改前: (1, 2, 3)
修改后: (100, 2, 3)

在上述示例中,modify_tuple 函数接受一个元组作为参数,并将该元组转换为列表。函数内部可以对列表进行修改,例如修改索引为0的元素为100。完成修改后,再将列表转换回元组,并将其返回。

需要注意的是,通过这种方式修改元组的值实际上是创建了一个新的元组,而不是直接在原始元组上进行修改。因为元组是不可变对象,在创建后无法修改其值。所以在函数调用后,原始元组的值并没有改变,而是返回了一个新的修改后的元组


全局变量

在 Python 中,当你在函数内部想要修改全局变量的值时,需要使用 global 关键字将变量声明为全局变量。

下面是一个示例代码,展示了如何在函数内部修改全局变量的值:

count = 0  # 全局变量

def increment():
    global count  # 声明 count 为全局变量
    count += 1  # 修改全局变量的值

print("初始值:", count)
increment()
print("修改后的值:", count)

结果:

               初始值: 0       
               修改后的值: 1

在上述示例中,count 是一个全局变量,在函数 increment 中我们想要将其值加1。为了告诉 Python 解释器在函数中使用全局变量 count,我们需要在 increment 函数内使用 global 关键字进行声明。

在函数内部使用 global count 表示 count 是一个全局变量,而不是函数内部的局部变量。这样,我们可以对全局变量 count 进行修改操作,使其增加1。

需要注意的是,在函数内部使用 global 声明全局变量后,对该变量的任何修改都会影响到全局作用域,因此要谨慎使用全局变量。通常,推荐在函数中通过参数传递和返回值来获取和修改变量的值,以避免全局变量带来的副作用。

def fun1(n):
    global n
    n=5
n=2
print(n)
fun1(n)
print(n)

注意上面代码是错误的,因为在全局声明之前分配了“n”,可改为:

def fun1():
    global n
    n=5
n=2
print(n)
fun1()
print(n)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流光焰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值