dictionary - 字典与 NamedTuples
问题描述
除了字典是可变的而 NamedTuple 不是,NamedTuple 可以通过位置和一些不同的符号来检索,在 Julia 中字典和 NamedTuple 之间是否还有其他显着差异?何时使用其中一种?
它们看起来很相似:
# Definition
d = Dict("k1"=>"v1", "k2"=>"v2")
nt = (k1="v1", k2="v2")
# Selection by specific key
d["k1"]
nt.k1
# Keys
keys(d)
keys(nt)
# Values
values(d)
values(nt)
# Selection by position
d[1] # error
nt[1]
解决方案
Julia 的一个显着区别是 NamedTuple 是它自己的类型,因此编译器可以专门处理特定的命名元组签名,而 Dictionary 方法必须从键中查找值。此外,NamedTuple 的每个值本身都可以是不同的类型,允许进一步优化和类型稳定性,超出字典所能实现的范围。如果我们稍微改变一下,让字典的类型是 Heterogeneous,这样它就是 type Dict{Symbol,Any}
,你可以看到它仍然是类型稳定的。
d=Dict(:k1=>"v1",:k2=>2.0)
nt=(k1="v1",k2=2.0)
foo(x) = x[:k2]
现在如果一个函数直接使用这个字典或命名元组,我们可以看到对于字典类型,结果是类型不稳定的,因为字典中的值只能由类型来保证Any
。
@code_warntype foo(d)
Body::Any
4 1 ─ %1 = invoke Base.ht_keyindex(_2::Dict{Symbol,Any}, :k2::Symbol)::Int64 │╻ getindex
│ %2 = (Base.slt_int)(%1, 0)::Bool ││╻ <
└── goto #3 if not %2 ││
2 ─ %4 = %new(Base.KeyError, :k2)::KeyError ││╻ Type
│ (Base.throw)(%4) ││
└── $(Expr(:unreachable)) ││
3 ─ %7 = (Base.getfield)(x, :vals)::Array{Any,1} ││╻ getproperty
│ %8 = (Base.arrayref)(false, %7, %1)::Any ││╻ getindex
└── goto #5 ││
4 ─ $(Expr(:unreachable)) ││
5 ┄ return %8
另一方面,NamedTuple 可以是类型稳定的。因为该字段是函数已知的,所以类型也被称为 a Float64
。
@code_warntype foo(nt)
Body::Float64
4 1 ─ %1 = (Base.getfield)(x, :k2)::Float64 │╻ getindex
└── return %1
推荐阅读
- python - 使用 pyspark 会话从本地文件读取时如何跳过一些行?
- c# - 带有文件和正文的 WebAPI 方法
- python - Python numpy for 循环,从列表创建列表并连接
- bootstrap-4 - 网格系统中的 Bootstrap 4 间距问题
- javascript - window.onpopstate 不起作用任何警报或控制台错误
- excel - 逐行,如果单元格 H= 单元格 I,则删除整行
- sql-server - 识别最高可能的数据类型
- c# - base64 编码是否对编码有任何字符串长度限制?
- android - 房间失效跟踪器在 1.1.1 中被初始化了两次
- javascript - 为什么 input[type=radio] 的默认值是 'on' 而不是 ''?