【发布时间】:2015-09-20 00:50:50
【问题描述】:
在回答一个与 Python 相关的问题时,我做了一些实验,发现了一个我无法弄清楚的与元组相关的事情:我很难理解为什么一个空元组比一个包含单个元素的元组占用更多空间(根据sys.getsizeof())。下面的代码是在 64 位 Debian Jessie 系统上使用 Python 2.7.9 的上游版本执行的(也使用 Python 3.4.2 进行了测试,其中值略有不同,但我所说的整体行为仍然存在):
>> sys.getsizeof(())
56
>> sys.getsizeof((1))
24
>> sys.getsizeof((1,2))
72
如您所见,空元组与单项元组存在很大差异(更准确地说是因子 2.3)。有什么想法吗?由于元组是递归数据结构,我假设sys.getsizeof() 返回的值是元组对象本身占用的内存量加上对它包含的对象的引用(如果元组将元素存储为引用而不是值 - 我不'不知道)。我最初的想法是,像字典一样的元组是在内存中创建的,具有一定的默认大小,可以容纳几个元素。我忘记了空字典为其保留内存的元素的确切数量,但这是我的意思,举个小例子:
>> sys.getsizeof({})
280
>> sys.getsizeof({"a":0})
280
>> sys.getsizeof({"a":0, "b":1})
280
但是,查看元组似乎并没有表现出相同的行为,因为元组在第一个元素添加到较小的大小后会缩小,然后随着每个元素的添加而增长(如预期的那样)。除此之外,列表似乎并没有遭受相同的行为:
>> sys.getsizeof([])
72
>> sys.getsizeof([1])
80
>> sys.getsizeof([1,2])
88
空列表在内存方面比具有 1 个或多个元素的列表小 - 完全正常。
我的第二个想法是单元素元组以某种方式转换为它包含的单个对象,并且所有这些都以某种方式包装,因此它看起来实际上是一个列表(这就是 len() 起作用的原因)。示例:
>> sys.getsizeof((1))
24
>> sys.getsizeof(1)
24
这似乎是可能的,但我不相信它真的会发生。
【问题讨论】:
-
(1)不是元组,它是一个整数,恰好被括在(语义上无意义的)括号中。你想要(1,)。 -
@Kevin 您应该补充说作为答案,这肯定是导致他经历的原因。刚刚在我的系统上做了一个快速测试,一个空元组需要 28 个字节的内存,加上每个元素 4 个字节。即,一个 1 元素元组需要 32 个字节。
标签: python python-2.7 python-3.x tuples