python 字典中的内存分配是如何工作的?

我想了解在将新数据添加到字典时,python 中的内存分配是如何工作的。在下面的代码中,我一直在等待每个新添加的数据最后都堆叠起来,但它并没有发生。


repetitions = {}

for item in new_deltas:

    list_aux = []

    if float(item[1]) <= 30:

        if float(item[0]) in repetitions:

            aux = repetitions[float(item[0])]

            aux.append(item[1])

            repetitions[float(item[0])] = aux

        else:

            list_aux.append(item[1])

            repetitions[float(item[0])] = list_aux

    print(repetitions)

我得到的结果如下。因此,我想了解为什么新的附加数据没有添加到堆栈的末尾,而是添加到堆栈的中间。


我的输入数据是:


new_deltas = [[1.452, 3.292182683944702], [1.449, 4.7438647747039795], [1.494, 6.192960977554321], [1.429, 7.686920166015625]] 

打印行输出:


{1.452: [3.292182683944702]}

{1.452: [3.292182683944702], 1.449: [4.7438647747039795]}

{1.452: [3.292182683944702], 1.494: [6.192960977554321], 1.449: [4.7438647747039795]}

{1.429: [7.686920166015625], 1.452: [3.292182683944702], 1.494: [6.192960977554321], 1.449: [4.7438647747039795]}



白衣非少年
浏览 157回答 2
2回答

POPMUISE

简短的回答字典被实现为哈希表而不是堆栈。没有倾向于打乱密钥顺序的额外措施哈希表在 Python 3.6 之前,字典中的排序是由散列函数随机化的。大致来说,它是这样工作的:d = {}&nbsp; &nbsp; &nbsp; &nbsp; # Make a new dictionary&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Internally 8 buckets are formed:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #&nbsp; &nbsp; [ [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] ]d['a'] = 10&nbsp; &nbsp;# hash('a') % s gives perhaps bucket 5:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #&nbsp; &nbsp; [ [ ] [ ] [ ] [ ] [ ] [('a', 10)] [ ] [ ] ]d['b'] = 20&nbsp; &nbsp;# hash('b') % s gives perhaps bucket 2:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; #&nbsp; &nbsp; [ [ ] [ ] [('b', 20)] [ ] [ ] [('a', 10)] [ ] [ ] ]因此,您可以看到此 dict 的排序会放在'b'前面,'a'因为哈希函数放在&nbsp;'b'较早的存储桶中。记住插入顺序的较新的哈希表从 Python 3.6 开始,还添加了一个堆栈。请参阅此概念验证,以更好地了解其工作原理。因此,dicts 开始记住插入顺序,并且这种行为在 Python 3.7 及更高版本中得到保证。在较旧的 Python 实现上使用 OrderedDict在 3.7 之前,您可以使用collections.OrderedDict()来获得相同的效果。更深的潜水对于那些有兴趣了解更多关于它是如何工作的人,我有一个37 分钟的视频,它从第一原理展示了用于制作现代 Python 字典的所有技术。

HUX布斯

在 Python 3.6 之前,字典没有排序(有关更多信息,请参阅此stackoverflow 线程)。如果您使用的是 Python 3.6 或更低版本(在 CPython 3.6 中,维护顺序的事实是一个实现细节,但在 Python 3.7 中它成为了一种语言特性),您可以使用OrderedDict来获得您想要的行为。例如,您可以将代码片段的开头更改为以下内容:from collections import OrderedDictrepetitions = OrderedDict()...
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python