Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将元组重新分配给新地址时,旧地址的值是否已清除?_Python_List_Tuples - Fatal编程技术网

Python 将元组重新分配给新地址时,旧地址的值是否已清除?

Python 将元组重新分配给新地址时,旧地址的值是否已清除?,python,list,tuples,Python,List,Tuples,我试图弄清楚python中的元组内存分配是如何工作的 skills = ("Python", "pandas", "scikit-learn") print(id(skills)) 这给了我一个值140555133913704 我修改这个元组以创建一个新元组 skills += ("ml","dl") print(id(skills)) 新地址是140555133738680 位于140555

我试图弄清楚python中的元组内存分配是如何工作的

skills = ("Python", "pandas", "scikit-learn")
print(id(skills))
这给了我一个值
140555133913704

我修改这个元组以创建一个新元组

skills += ("ml","dl")
print(id(skills))
新地址是
140555133738680

位于
140555133913704
的元组对象是否已删除,地址是否已清除


与修改列表相比,修改元组是否更节省空间?

这是因为元组是不可变的,并且它们不能更改。在您的示例中,向元组添加元组将创建一个新元组并将其分配给相同的名称。它不会更改该名称最初引用的元组对象

  • 将不会删除位于140555133913704的元组对象。它将具有以前的值i-e(“Python”、“pandas”、“scikit learn”)
  • 元组比列表更节省空间。列表被过度分配以加快追加速度

python中除了原语之外的所有东西都是对象,因此键入时:

skills = ("Python", "pandas", "scikit-learn")
您正在创建一个元组对象,对该对象的引用将存储在您声明的skills变量中。
在第二步中,除了“ml”和“dl”之外,还使用最后一个元组的值创建另一个tuple对象。现在,您的skills变量中有了新对象的引用。 最后一个怎么了?嗯,它仍然存在,但现在它是一个未引用的对象,python垃圾收集器将清除它。
关于列表,python中的列表也是一个对象,它与数据和一个“len”属性一起存储,该属性指示数组的长度,因此,如果向列表中添加了一些内容,那么这种情况将再次发生,尽管列表是可变对象!(事实上,我对此表示怀疑,并亲自尝试了一下,结果它变了:))因此,垃圾收集器会在一段时间后再次删除未引用的对象

>>> list = [1,2,3]
>>> id(list)
2214374343624
>>> list = list + [2,3]
>>> list
[1, 2, 3, 2, 3]
>>> id(list)
2214472730440

这回答了你的问题吗?在代码中,旧元组将被垃圾收集。但是,如果您先执行“x=skills”,则旧元组将继续存在。请查看原始
skills
的id,并通过调用
ctypes.cast(…)
自行尝试。你会看到它仍然在那里。但它最终将被gc’ed。请记住,Python语言没有任何内存地址的概念。该语言只定义对象都存在于一个“堆”中;理论上,堆可以是(比如)SQL数据库,而不是内存。而且,
id
仅返回唯一标识符;使用内存地址作为标识符是一个CPython实现细节。