python里字典是无序的

详情请参考:https://www.zhihu.com/question/65855807

关于 Python 字典的 values() 方法返回值的顺序?

dict_mark = {'Wang': 'C', 'Li': 'B', 'Ma': 'A'}
s = ''
for c in dict_mark.values():
    s += c
print(s)

关于这个字典打印出来一直是 CBA 的顺序,可是字典不是应该无序吗?stackoverflow的前辈们的答案我看的一知半解,能否请教知友们呢?

问题地址

另一答案地址

还有一个关于 dictionary 的(字典变有序了?)

关注者

38

被浏览

8,727

关注问题写回答

​添加评论

​分享

​邀请回答

收起

12 个回答

默认排序​

廖雪峰

廖雪峰

业余马拉松选手 http://www.liaoxuefeng.com

43 人赞同了该回答

规范是指dict遍历是不保证顺序的,但一定保证每个元素都被遍历一次

实现可以是无序,也可以是有序,都符合规范

Py3.5是无序的,3.6是有序的,但不能说dict就是有序的,因为如果3.7改成无序的也是正确的实现。

如果要使用有序dict,必须用OrderedDict

发布于 2017-09-26

​赞同 43​​10 条评论

​分享

​收藏​感谢

Coldwings

Coldwings

Python 话题的优秀回答者

9 人赞同了该回答

如果按照语言规范来看,Python的规范里没有说明Dict是一个有序的类型。换句话说,dict就是无序的,因为语言规范不保证它按照什么顺序出来。要有序,请使用OrderedDict。

但是无序不是说每次输出结果都不同,无序只是指结果不保证一定与插入顺序一致而已。

CPython 3.6里对dict有个新的实现,使得字典内部存储的顺序不仅仅与key有关,还与插入顺序有关。但是有关并不代表它就一定按照插入顺序依次出现(似乎当字典实现在内存中进行扩展的时候就可能造成结果不一致),只不过表示如果key相同,插入顺序相同,那么结果也是相同的。

在此之前,用values和keys方法取到的list仅与key(准确的说是key的__hash__)有关而与插入顺序无关。

编辑于 2017-09-25

​赞同 9​​4 条评论

​分享

​收藏​感谢

灵剑

灵剑

微博一般不上 http://weibo.com/hubo1016

21 人赞同了该回答

无序的不代表随机的,也不代表每次都是随机的,这些词有细微的差异。无序的只是说,你不该对顺序有任何假定,既不能假定有确定顺序,也不能假定没有确定顺序。

发布于 2017-11-17

​赞同 21​​6 条评论

​分享

​收藏​感谢

Pegasus Wang

Pegasus Wang

知乎 Python 后端工程师,Pythonista and Vimer

1 人赞同了该回答

Python dictionary implementation

你看下 dict 的 CPython hash 实现就了解了

发布于 2017-11-17

​赞同 1​​添加评论

​分享

​收藏​感谢

Revive

Revive

码农 / 死宅 / 玩家

1 人赞同了该回答

一般语言里的dict结构只是表面上说自己是无序的,实际上根据内部实现会有自己的一套顺序,只是这个顺序可能比较古怪,比较混沌,比较没有统一标准,甚至可能以后实现变了顺序也会变,所以设计者也不想告诉你究竟是个什么顺序,但是每次读出来都会根据这个顺序出。
不过也有比较奇葩的语言每次读出来的顺序都不一样,比如说golang。

编辑于 2017-09-26

​赞同 1​​添加评论

​分享

​收藏​感谢

李强

李强

1 人赞同了该回答

Python内部对key的索引是有序的,具体我举个例子.

In [6]: hash("acc")&7

Out[6]: 2

In [7]: hash("abc")&7

Out[7]: 4

In [8]: {"acc":"acc","abc":"abc"}

Out[8]: {'abc': 'abc', 'acc': 'acc'}

输入字典顺序是先key"acc"后key"abc",输出位置就倒了.

当然除了整数hash("key")&7的值好像每次重新开一个Python解释器都会变.所以说可能你的hash("abc")&7这个值也会和我的不一样.

回到你的问题.

In [9]: hash('Wang')&7

Out[9]: 1

In [10]: hash('Li')&7

Out[10]: 1

In [11]: hash('Ma')&7

Out[11]: 5

In [12]: {'Wang': 'C', 'Li': 'B', 'Ma': 'A'}

Out[12]: {'Li': 'B', 'Ma': 'A', 'Wang': 'C'}

我现在的字典顺序就变了呢.

但是实际上这个返回顺序并不重要.

编辑于 2017-11-17

​赞同 1​​添加评论

​分享

​收藏​感谢收起​

绫波limbo

绫波limbo

我爱python一辈子

2 人赞同了该回答

没有顺序,包括.keys取键,.values取值,字典无序存储不是逗你玩的,不管你在命令行里输出多少次一样的顺序都不要上当!!!
如果要取字典顺序,请你老老实实用ordereddict!!
这是我有一次在spark做需求的血泪教训

发布于 2017-09-26

​赞同 2​​2 条评论

​分享

​收藏​感谢

梧桐

梧桐

答非所问的 见一个举报一个 呵呵 继续抖机灵给我看

字典是有顺序的 但是顺序是不定的 不信你可以迭代试试

发布于 2017-11-24

​赞同​​添加评论

​分享

​收藏​感谢

Tux ZZ

Tux ZZ

Nothing-to-research Researcher

补充 

@灵剑

 的回答。
cpython3.6的dict实现搬了pypy的实现,是保持顺序的。
** 但你依然不能把dict当作有序的来使用 **
因为dict的标准规定*不保证*有顺序,要保证有顺序的请用OrderedDict

编辑于 2017-11-22

​赞同​​添加评论

​分享

​收藏​感谢

ShengCiun Liang

ShengCiun Liang

反对任何形式的平权

理论上肯定有序的 你既然有放入的顺序 查看肯定就有顺序 只是不可以顺序的方式看待

发布于 2017-11-20

​赞同​​添加评论

​分享

​收藏​感谢

陈子坤

陈子坤

结构工程师,Python,Go, 大数据, WEB后端

字典是无序的,这句话是对的。但是字典的存储过程却是按顺序的。

字典的存储背后的逻辑是散列表,也就是稀疏数组。dict初始化之后,Python解释器会给dict分配一定的空间,往字典里添加是按顺序添加的。

但是,如果如果继续往字典里添加新键,有可能会引起Python解释器对存储空间的扩容,扩容的过程会新建散列表,然后复制已有的元素到新散列表,这个过程可能会引起散列冲突,导致dict的键值对的次序发生变化。

《流畅的Python》一书有关于字典的存储更为详细的介绍。

如果不了解散列表,可以查资料。

编辑于 2017-11-18

​赞同​​添加评论

​分享

​收藏​感谢匿名用户

匿名用户

values 和 keys 保持遍历时键对对应顺序一致。

猜你喜欢

转载自blog.csdn.net/djs123DJS/article/details/83240158