Dict的排序规则

Dict("A" => 1, "B" => 2.5, "D" => 2 - 3im)

结果为
Dict{String, Number} with 3 entries:
“B” => 2.5
“A” => 1
“D” => 2-3im

为什么B在A前?

Dict 本来就是没有顺序的,不要问为什么没有顺序。
需要顺序请用 Vector

ulia> Z=[("A",1),("B",2),("C",3)]
3-element Vector{Tuple{String, Int64}}:
 ("A", 1)
 ("B", 2)
 ("C", 3)
1 个赞

JuliaCollections/OrderedCollections.jl: Julia implementation of associative containers that preserve insertion order

Dictionary在很多其他语言中也被叫做Unordered list。没有顺序是因为Dict中是通过Hash table构建函数映射的,你无法比较两个函数的大小。

谢谢!
那么

for (key, value) in Dict("A" => 1, "B" => 2.5, "D" => 2 - 3im)
    println("$(key): $(value)")
end

输出结果:

B: 2.5
A: 1
D: 2 - 3im

这个顺序是固定的吗?它在功能上是无序的,但在编程语言底层,这个顺序是根据什么原则排的?

刚搜了一下Python

大概是3.7以后的版本保证了insertion order。这完全取决于实现。

Julia中目前的我也不清楚。翻到了Jeff很多年前的尝试

1 个赞

和字典的设计有关。

比如 Python 字典的键值和创建顺序相关,比如

>>> a = {}; a[2] = 1; a[1]=1;list(a)
[2, 1]
>>> a = {}; a[1] = 1; a[2]=1;list(a)
[1, 2]
>>> a = {}; a[1] = 1; a[2]=1;a[1]=1;list(a)
[1, 2]

或者

from random import sample
keys = sample(range(1000), 1000)
dt = {i:1 for i in keys}
assert list(dt) == keys

一些算法题可以用这个特性来做,但同上边说的,字典和集合类似,本就不该考虑序结构。


Julia 键值和创建顺序无关,比如

using Test
using StatsBase: sample
keys1 = sample(1:1000, 1000, replace=false)
dict1 = Dict(zip(dict1, fill(1, 1000)))

# 字典的键值顺序和输入顺序无关
@test first.(collect(dict1)) != keys1

此外,用 @edit Dict(1=>2) 可以查看 Dict 源码。

需要有序字典的话,可以从其他库导入

using DataStructures: OrderedDict
a = OrderedDict(1=>1, 2=>1, 3=>1, 0=>1)
sort!(a)

键值按创建顺序排列

知道是功能上无序就行了。
顺序算是实现的细节,试图依赖这些细节容易在版本升级时出问题。


一定要了解实现可以去看计算 hash 部分的源码:

谢谢楼上的各位! :pray: