Python字典插入和删除

Python字典插入和删除,python,python-2.7,Python,Python 2.7,运行这个之后,我得到了 删除前: print("Before deleting:\n") od = {} od['a'] = 1 od['b'] = 2 od['c'] = 3 od['d'] = 4 for key, value in od.items(): print(key, value) print("\nAfter deleting:\n") od.pop('c') for key, value in od.items(): print

运行这个之后,我得到了

删除前:

print("Before deleting:\n") 

od = {}

od['a'] = 1

od['b'] = 2

od['c'] = 3

od['d'] = 4

for key, value in od.items(): 

    print(key, value) 

print("\nAfter deleting:\n") 

od.pop('c') 

for key, value in od.items(): 

    print(key, value) 

print("\nAfter re-inserting:\n") 

od['c'] = 3

for key, value in od.items(): 

      print(key, value)
('a', 1)
('c', 3)
('b', 2)
('d', 4)
删除后:

print("Before deleting:\n") 

od = {}

od['a'] = 1

od['b'] = 2

od['c'] = 3

od['d'] = 4

for key, value in od.items(): 

    print(key, value) 

print("\nAfter deleting:\n") 

od.pop('c') 

for key, value in od.items(): 

    print(key, value) 

print("\nAfter re-inserting:\n") 

od['c'] = 3

for key, value in od.items(): 

      print(key, value)
('a', 1)
('c', 3)
('b', 2)
('d', 4)
重新插入后:

('a', 1)
('b', 2)
('d', 4)
我的问题是为什么
c
插入到第二位,而对于记录,无论
c
的值是什么,它总是插入到第二位。
提前感谢

请注意,python中的字典是无序的-因为字典中的值是由键索引的,所以它们没有任何特定的顺序。

python字典是使用哈希表实现的。它是一个数组,其索引是通过对键使用哈希函数获得的

对于任何给定的键(假设它是一个字符串),它首先通过一个哈希函数,然后用(arr_size-1)屏蔽它。整个:hash_func('a')&(arr_size-1)给出数组中键值对的索引

指数(n=8)(k,v)

(a,1)-h('a')&7-->0(a,1)

(b,2)-h('b')&7-->1(b,2)

(c,1)-h('c')&7-->2(c,3)

这就是为什么键“c”的索引没有改变的原因


从Python3.7开始,Python字典的插入顺序是有保证的

您实际上是在Python2上,而不是在Python3上,您的
打印输出证明了这一点
print
是Python2上的一条语句(在顶部禁止您的代码包括来自uuu future\uuuuuu import print\u函数的
),而不是函数调用(就像在Py3上,或者在Py2上使用
\uuuuu future\uuuuu
导入),因此括号只是生成了一个
元组,您打印了它

在Python 3.6之前,
dict
s没有有用的顺序(它与键的散列有关,但冲突解决意味着顺序可以更改,因为
dict
是以不同的顺序构造的),但是重新插入给定的键通常(不保证)会将其放在同一个存储桶中,将其保持在相同的迭代位置


如果您正在寻找插入顺序行为(希望
'c'
移到末尾),可以升级到Python 3.6+(3.7+需要保证,但所有现有的3.6解释器都将其作为实现细节),或者使用
集合。OrderedDict

您正在运行的Python的哪个次要版本?它不应该像3.6+中那样(插入顺序
dict
s),但早期版本是“哈希顺序,但在冲突中跳跃”,这实际上相当于“没有有用的顺序可言”。我只是在Geeksforgeks中使用编辑器。感谢在python解释器的通用版本中提供的帮助,c总是在后面加上d@SauravSaha:不,没有。这是3.6中的一个新特性(3.7是语言标准首次保证的)。3.5或更早版本的解释器不会有这种行为。@SauravSaha:是的,有一个字符串/字节类的每次运行哈希种子,它会干扰它们的哈希(以防止恶意用户提交选择了冲突哈希的条目的拒绝服务攻击),所以在插入排序之前,在3.3中默认打开散列种子后(即使是现在,对于
set
s,
str
(以及
字节
日期时间
以及以某种方式遵从其散列的任何其他内容)的顺序将因运行而异,即使是在同一个解释器上。所以每次生成输出时,我应该得到不同的顺序,但这是一个预定义的顺序,它们在3.6+中是插入顺序。OP使用的是Python2(其
print
输出为
tuple
s就证明了这一点)。OP使用的是Python2(他们的
print
输出是
tuple
s就证明了这一点)。。。他们没有得到插入顺序。如果我想在第三个位置插入c,我该怎么做that@A_the_kunal:你不能。或者更准确地说,如果没有
OrderedDict
,您根本无法在3.6之前完成它。如果您使用3.6+
dict
OrderedDict
,则从开始的第三个位置将使用
'c'
构建它(删除它并读取它会将其移动到末尾)。如果它的顺序不正确,并且您无法更改它的创建方式,那么您需要大量手动弹出和重新插入,或者更简单地说,您只需获得
列表(mydict.items())
,按照您的意愿对
列表进行重新排序,然后使用
dict
/
orderedict
构造函数进行转换。