为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

白衣非少年 2022-07-12 10:20:53
我想了解在将新数据添加到字典时,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]}
查看完整描述

2 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

简短的回答

字典被实现为哈希表而不是堆栈。

没有倾向于打乱密钥顺序的额外措施

哈希表

在 Python 3.6 之前,字典中的排序是由散列函数随机化的。大致来说,它是这样工作的:

d = {}        # Make a new dictionary

              # Internally 8 buckets are formed:

              #    [ [ ] [ ] [ ] [ ] [ ] [ ] [ ] [ ] ]

d['a'] = 10   # hash('a') % s gives perhaps bucket 5:

              #    [ [ ] [ ] [ ] [ ] [ ] [('a', 10)] [ ] [ ] ]

d['b'] = 20   # hash('b') % s gives perhaps bucket 2:

              #    [ [ ] [ ] [('b', 20)] [ ] [ ] [('a', 10)] [ ] [ ] ]

因此,您可以看到此 dict 的排序会放在'b'前面,'a'因为哈希函数放在 'b'较早的存储桶中。

记住插入顺序的较新的哈希表

从 Python 3.6 开始,还添加了一个堆栈。请参阅此概念验证,以更好地了解其工作原理。

因此,dicts 开始记住插入顺序,并且这种行为在 Python 3.7 及更高版本中得到保证。

在较旧的 Python 实现上使用 OrderedDict

在 3.7 之前,您可以使用collections.OrderedDict()来获得相同的效果。

更深的潜水

对于那些有兴趣了解更多关于它是如何工作的人,我有一个37 分钟的视频,它从第一原理展示了用于制作现代 Python 字典的所有技术。


查看完整回答
反对 回复 2022-07-12
?
HUX布斯

TA贡献1876条经验 获得超6个赞

在 Python 3.6 之前,字典没有排序(有关更多信息,请参阅此stackoverflow 线程)。如果您使用的是 Python 3.6 或更低版本(在 CPython 3.6 中,维护顺序的事实是一个实现细节,但在 Python 3.7 中它成为了一种语言特性),您可以使用OrderedDict来获得您想要的行为。


例如,您可以将代码片段的开头更改为以下内容:


from collections import OrderedDict

repetitions = OrderedDict()

...


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号