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

news2024/9/27 21:22:30

目录

前言

列表、字典(可变对象)

元组(不可变对象)

全局变量


前言

今天在写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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/838286.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ - 模板分离编译

模板分离编译 我们先来看一个问题&#xff0c;我们用 stack 容器的声明定义分离的例子来引出这个问题&#xff1a; // stack.h // stack.h #pragma once #include<deque>namespace My_stack {template<class T, class Container std::deque<T>>class stack…

Python 开发工具 Pycharm —— 使用技巧Lv.3

单步执行调试 1&#xff1a; 鼠标左键单击红点是断点行 2&#xff1a;甲虫样式是进行调试方式运行&#xff0c;鼠标左键单击点击 3&#xff1a; 单步运行图标&#xff0c;点击让程序运行一行 4&#xff1a; 步入步出&#xff0c;可以进入当前代码行函数内 5&#xff1a;重新运行…

JSON.stringify()与JSON.parse()没有你想的那样简单

重新学习这两个API的起因 在本周五有线上的项目&#xff0c;16:30开始验证线上环境。 开始都是顺顺利利&#xff0c;一帆风顺。 大概17:50左右&#xff0c;我正在收拾东西。 准备下班去王者峡谷骑着我的船溜达一圈。 可是天降意外&#xff0c;给我派了一个bug。 测试给我说&am…

山西电力市场日前价格预测【2023-08-06】

日前价格预测 预测明日&#xff08;2023-08-06&#xff09;山西电力市场全天平均日前电价为411.77元/MWh。其中&#xff0c;最高日前电价为457.52元/MWh&#xff0c;预计出现在19: 30。最低日前电价为370.37元/MWh&#xff0c;预计出现在13: 15。 价差方向预测 1&#xff1a; 实…

海外应用商店优化实用指南之关键词

和SEO一样&#xff0c;关键词是ASO中的一个重要因素。就像应用程序标题一样&#xff0c;在Apple App Store和Google Play中处理应用程序关键字的方式也有所不同。 关键词研究。 对于Apple&#xff0c;我们的所有关键词只能获得100个字符&#xff0c;Google Play没有特定的关键…

数据结构10 -查找_树表查找

创建二叉搜索树 二叉搜索树 二叉搜索树是有数值的了&#xff0c;二叉搜索树是一个有序树。 若它的左子树不空&#xff0c;则左子树上所有结点的值均小于它的根结点的值&#xff1b; 若它的右子树不空&#xff0c;则右子树上所有结点的值均大于它的根结点的值&#xff1b; 它…

47.Linux学习day01 基础命令详解1(很全面)

目录 一、Linux和Windows的区别 二、Linux系统目录结构 常见目录说明 三、Linux常见的基础命令 1.pwd 2.cd 3.ls 4.man 5. touch 6.mkdir 7. rmdir 今天正式学习了linux的一些基础操作和基础知识&#xff0c;以及linux和windows的区别。 一、Linux和Windows的区…

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接

SpringMVC基于SpringBoot的最基础框架搭建——包含数据库连接 背景目标依赖配置文件如下项目结构如下相关配置如下启动代码如下Controller如下启动成功接口调用成功 背景 工作做了一段时间&#xff0c;回忆起之前有个公司有线下笔试&#xff0c;要求考生做一个什么功能&#x…

建设全球研发中心城市,长沙与人才何以双向奔赴?

跨越山涧峡谷&#xff0c;需要搭建钢铁桥梁&#xff0c;跨越文化沟通&#xff0c;需要搭建互相理解的桥梁&#xff0c;那么&#xff0c;一座城市与人才之间的联系&#xff0c;应该搭建怎样的桥梁&#xff1f; 近日&#xff0c;长沙出台了重磅文件《中共长沙市委长沙市人民政府…

XSS漏洞原理及利用跨站请求伪造CSRF

XSS漏洞原理及利用&跨站请求伪造CSRF XSS一、案例二、什么是XSS三、XSS危害四、XSS的分类4.1、反射型XSS4.1.1、介绍4.1.2、利用过程 4.2、存储型XSS4.2.1、介绍4.2.2、利用过程4.2.3、案例 4.3、DOM型XSS4.3.1、介绍4.3.2、常用的DOM方法4.3.3、案例4.3.3.1、代码分析4.3.…

Spring源码之XML文件中Bean标签的解析1

读取XML文件&#xff0c;创建对象 xml文件里包含Bean的信息&#xff0c;为了避免多次IO&#xff0c;需要一次性读取xml文件中所有bean信息&#xff0c;加入到Spring工厂。 读取配置文件 new ClassPathResource("applicationContext.xml")ClassPathResource是Sprin…

vue动态生成行

vue代码 <el-table :data"form.lineInfos" :bordertrue style"width: 99.99%;"> <el-table-column type"index" label"序号" width"50"></el-table-column> <el-table-column prop"unitPrice&qu…

【Linux 网络】 传输层协议之TCP协议 TCP的三次握手和四次挥手

TCP协议 TCP协议段格式谈谈什么是 “可靠” 和 “不可靠”TCP协议段——序号与确认序号TCP协议段——窗口大小TCP协议段 —— 六个标志位确认应答机制&#xff08;ACK&#xff09;超时重传机制连接管理机制TCP 的三次握手四次挥手TCP三次握手四次挥手总结图 滑动窗口流量控制拥…

18. SpringBoot 如何在 POM 中引入本地 JAR 包

❤️ 个人主页&#xff1a;水滴技术 &#x1f338; 订阅专栏&#xff1a;成功解决 BUG 合集 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; Spring Boot 是一种基于 Spring 框架的轻量级应用程序开发框架&#xff0c;它提供了快速开发应用程…

第126天:内网安全-隧道技术SSHDNSICMPSMB上线通讯LinuxMac

知识点 #知识点&#xff1a; 1、入站规则不出网上线方案 2、出站规则不出网上线方案 3、隧道技术-SMB&ICMP&DNS&SSH 4、控制上线-Linux&Mac&IOS&Android-连接方向&#xff1a;正向&反向&#xff08;基础课程有讲过&#xff09; -内网穿透&#xf…

vue2-vue项目中你是如何解决跨域的?

1、跨域是什么&#xff1f; 跨域本质是浏览器基于同源策略的一种安全手段。 同源策略&#xff08;sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也是最基本的安全功能。 所谓同源&#xff08;即指在同一个域&#xff09;具有以下三个相同点…

Java对象的前世今生

文章目录 一、创建对象的步骤二、类加载机制三、内存分配指针碰撞 (内存连续)空闲列表 (内存不连续) 四、创建对象的5种方法五、浅拷贝与深拷贝 以下一行代码内部发生了什么&#xff1f; Person person new Person();一、创建对象的步骤 根据JLS中的规定&#xff0c;Java对象…

牢记这16个SpringBoot 扩展接口,写出更加漂亮的代码

1、背景 Spring的核心思想就是容器&#xff0c;当容器refresh的时候&#xff0c;外部看上去风平浪静&#xff0c;其实内部则是一片惊涛骇浪&#xff0c;汪洋一片。Springboot更是封装了Spring&#xff0c;遵循约定大于配置&#xff0c;加上自动装配的机制。很多时候我们只要引…

Scala编程语言入门教程

Scala教程 方便个人学习和查阅 学习目标 Scala介绍 简介 Scala创始人Martin Odersky马丁奥德斯基 再回到我们的scala语言&#xff0c;在Scala官网https://www.scala-lang.org/介绍了其六大特征。 Java和scala可以混编 类型推测(自动推测类型) 并发和分布式&#xff08;Ac…

nginx的优化和防盗链 重要!!!

实验一、隐藏版本号 要把nginx的版本号隐藏起来&#xff0c;防止恶意攻击 方法一&#xff1a;修改配置文件 在http模块中加入一个命令 server_token off&#xff1b; 过程&#xff1a; 备份&#xff0c;改配置文件一定要备份 修改配置文件 在http模块中添加 server_tokens …