我在玩全局变量和局部变量,注意到列表和整数的不同之处.

当我按照预期运行下面的代码时,为整数类型创建了两个不同的局部和全局变量.

a = 10
def fun(a):
    a = a + 1
    print(a)
    print(id(a))

fun(a)
print(a)
print(id(a))

但当我为一个列表做同样的事情时,一些非常奇怪的事情发生了.在下面的代码中,函数内部和外部的变量具有相同的id.

a = [10, 12]
def fun(a):
    a *= 3
    print(a)
    print(id(a))

fun(a)
print(a)
print(id(a))

这可能有一个解释,我想,如果有人知道,我很想知道原因,当然,但它变得疯狂,当我做了一个非常小的改变第三行,我不能把我的手指为什么.下面的代码将再次具有不同的全局和局部变量.

a = [10, 12]
def fun(a):
    a = a * 3
    print(a)
    print(id(a))

fun(a)
print(a)
print(id(a))

如果有人能解释为什么列表会改变事情,以及为什么不使用短格式操作符来改变事情,那将是非常感激的!Python 3.10.6

推荐答案

在Python中,整数是不可变的对象,这意味着当你向函数传递一个整数时,会创建该整数的新副本.这就是为什么在第一个代码片段中看到全局变量和局部变量的不同ID.

另一方面,列表在Python中是可变对象.当您在列表上使用*=操作符时,您正在修改原始列表.这意味着全局变量和局部变量指向同一个list对象,因此它们具有相同的ID.

当您在列表上使用*操作符而不是*=时,创建了一个新的列表对象并将其分配给局部变量a.这就是为什么在第三个代码片段中看到全局变量和局部变量的不同ID.

因此,总的来说,代码中整数和列表之间的行为差异是由于Python中列表的可变性.对象是不可变的,所以当传递给函数时,它们的行为与列表等可变对象不同.

Python-3.x相关问答推荐

使用魔方无法从图像中识别单个字符

Python根据阈值对数字进行分组

Pandas :从元组字典创建数据帧

Python避免捕获特定异常

如何在matplotlib中显示次要刻度标签

PySpark每毫秒使用先前的值填充数据

我正在try 从 10*3 矩阵中删除随机值并将其变为 10*2 矩阵

如何获取实例化 `types.GenericAlias` 的下标类?

如何统计一个值连续出现的次数?

如何在 Python 中 cv2 的窗口标题上动态更新 FPS

有没有办法使用重采样矢量化添加缺失的月份?

Python pandas将单元格值移动到同一行中的另一个单元格

PySpark python 问题:Py4JJavaError: An error occurred while calling o48.showString

如何使用python将放置在多个嵌套文件夹中的文档移动和重命名为一个新的单个文件夹?

作为函数对象属性的 __kwdefaults__ 有什么用?

Python中的多行日志(log)记录

在 Python 3 中获取所有超类

Python的max函数有多高效

Selenium Python - 处理没有这样的元素异常

finally 总是在 try 块返回之前运行,那么为什么 finally 块中的更新不会影响 try 块返回的变量的值呢?