Python字典能力会动态增加吗?
假设在Python3中,我们使用了一个字典,例如:
my_dct = {}
...
for i in range(100):
my_dct[i] = True
...
for s in "potentially long string":
my_dct[s] = True
我的问题是,当我们通过Python解释器运行上述Python程序时,解释器在第一行会创建什么容量容器?根据这一大小,循环的第一或第二个过程中的容量会增加吗?
此链接显示容量显示容量8。 =“ https://github.com/python/cpython/cpython/blob/main/objects/dictobject.c” rel =“ nofollow noreferrer”> this 根据类型,128、2^15等显示。
非常感谢任何解释,谢谢。
Let's say in python3, we used a dictionary as:
my_dct = {}
...
for i in range(100):
my_dct[i] = True
...
for s in "potentially long string":
my_dct[s] = True
My question is when we run the above python program through the python interpreter, what capacity container does the interpreter create at the first line? Depending on this size, does the capacity increase during the course of the first or second for loop?
This link shows capacity 8. While this shows, according to the type, 128, 2^15, etc. as the capacity of the container upon the instantiation of a dictionary in python.
Would really appreciate any explanation, thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
dict
存储如何随着增长而调整是一个实现细节,大多数用户不需要知道。如果您是开发人员,或者想在C中编写自己的代码,则详细信息可能很有用。但是,对于在列表和dicts之间进行选择,它们无关紧要。列表和dicts之间的重要区别在于它们的索引方式。列表由整数(或切片)索引,并且“包含”所有值,直到其
len
。一个键是由键索引的,这可以是任何可用对象。字符串最常见。从表面上看,这两个对象是等效的:
两个都有
len()
100,并且可以以相同的方式进行索引:糟糕,我的意思是使用
alist = [thue in range in range(100) )
,100true
值的列表,而不是list(range(100))
。但这不会改变以下讨论。一个关键区别是列表索引必须是连续的。那就是我们要使用
alist [200]
,我们将不得不在列表中添加另外101个值。而adict [200] = false
简单地将200
添加到哈希表中,而新的len
101。基础存储非常不同。
alist
具有一个C数组,其中包含100个值的参考,再加上一些“头部空间”,以允许使用alist.Append(...)
快速增长。ADICT
具有哈希表,该表以某种方式存储了对密钥和值的引用。在这两种情况下,随着它们的成长,存储(“容器”?)填充时必须重新分配。同样,详细信息取决于实现,并且用户在很大程度上看不见 - 除非我们仔细跟踪内存或时间。
我已经看到了许多问题,这些问题尝试比较列表和数组的
getizeof
。答案总是指出,这种比较的价值有限,因为它测量了截然不同的事情。对于
list
,getsizeof
基本上是存储价值引用的C数组的大小。对于100的len(alist)
,即8*100字节,大约13个值的增长空间 - 此时必须重新分配。添加6个值不会改变大小:
再增加6个,强制一个重新安装,具有较大的头部空间(用于27个参考):
我假设
getsizeof(adict)
测量了标签的大小。那要大得多。将12个密钥添加到
ADICT
不会更改大小。有足够的空间来处理这些值而没有冲突。对于总记忆脚打印,我们还必须考虑键和值的内存使用。在这些示例中,这并不多,因为所有引用
true
引用同一对象。并且最多255个int也是统治和独特的。但是钥匙可以是字符串,元组或更复杂的对象。值可以是一个对象,尽管将它们添加到列表或DICT确实会增加内存使用。它们是通过引用而不是价值存储的。How the
dict
storage adjusts as it grows is an implementation detail, which most users don't need to know. If you are developer, or want to write your own code in C, the details may be useful. But for choosing between lists and dicts, they don't matter.The important difference between lists and dicts is how they are indexed. A list is indexed by integers (or slices), and 'contains' all values up to its
len
. A dict is indexed by keys, which can be any hashable object. Strings are most common.On the surface these two objects are equivalent:
Both have
len()
100, and can be indexed the same way:Oops, I meant to use
alist = [True for i in range(100)]
, a list of 100True
values, rather thanlist(range(100))
. But that doesn't change the following discussion.A key difference is that the list indices have to be consecutive. That is if we want to use
alist[200]
, we will have to add another 101 values to the list. Whereasadict[200]=False
simply adds the200
to the hash table, with a newlen
of 101.Underlying storage is quite different.
alist
has a C array that contains references for 100 values, plus some 'head room' to allow for fast growth withalist.append(...)
.adict
has a hash table, that somehow stores references to the keys and the values.In both cases, as they grow, the storage ('container'?) will have to be reallocated when it fills up. Again the details are implementation dependent, and largely invisible to users - unless we carefully track memory or times.
I've seen a number of SO questions that try to compare the
getsizeof
of list and arrays. The answers always point out that this comparison has limited value, since it measures very different things.For a
list
,getsizeof
is basically the size of the C array that stores value references. Forlen(alist)
of 100, that's 8*100 bytes, with roughly growth space for 13 more values - at which point it will have to be reallocated.Adding 6 values does not change size:
Adding another 6, forces a reallocation, with a larger head space (for 27 references):
I assume the
getsizeof(adict)
measures the size of the hashtable. That's quite a bit larger.Adding 12 more keys to
adict
doesn't change the size. There's enough space to handle these values without clashes.For total memory foot print we also have to consider the memory use of the keys and values. In these examples, that isn't much, since all references to
True
reference the same object. And ints up to 255 are also preallocated and unique. But keys can be strings, tuples, or more complex objects. And values can be an object, though adding them to a list or dict does increase memory use. They are stored by reference, not value.