目录
前言
今天在写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)