Ant*_*llo 1 dictionary tuples namedtuple julia
除了该词典是可变的,NamedTuple没有,那NamedTuple可以通过位置有点不同符号的检索,是否有其他的朱莉娅字典和NamedTuples之间显著的差异?何时使用其中一种?
他们看起来很相似:
# 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]
Run Code Online (Sandbox Code Playgroud)
小智 6
Julia的一个显着区别是NamedTuple是它自己的类型,因此编译器可以专注于那个特定的命名元组签名,而Dictionary方法必须从键中查找值.此外,NamedTuple的每个值本身可以是不同的类型,允许进一步优化和类型稳定性超出字典中可实现的范围.如果我们更改它以使字典的类型是异构的,以便它是类型的Dict{Symbol,Any}
,你可以看到它仍然是类型稳定的.
d=Dict(:k1=>"v1",:k2=>2.0)
nt=(k1="v1",k2=2.0)
foo(x) = x[:k2]
Run Code Online (Sandbox Code Playgroud)
现在,如果一个函数直接使用这个字典或者命名为tuple,我们可以看到字典类型,结果不是类型稳定的,因为Dictionary中的值只能通过类型来保证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
Run Code Online (Sandbox Code Playgroud)
另一方面,NamedTuple可以是类型稳定的.因为该字段是由函数知道的,所以该类型也是已知的Float64
.
@code_warntype foo(nt)
Body::Float64
4 1 ? %1 = (Base.getfield)(x, :k2)::Float64 ?? getindex
??? return %1
Run Code Online (Sandbox Code Playgroud)
将其NamedTuple
视为struct
Julia 中的匿名而不是Dict
. 特别是存储异构类型NamedTuple
是类型稳定的。
请注意,这也是 Python 和 Julia 在思维上的主要差异。在 Julia 中,如果您希望代码运行得更快,您通常会关心类型推断。