代码之家  ›  专栏  ›  技术社区  ›  Antonello

字典与命名副本

  •  0
  • Antonello  · 技术社区  · 7 年前

    除了字典是可变的,而不是命名的,这个命名的可以通过位置和一点不同的符号来检索,是吗? 其他 Julia的字典和名字成绩单有显著差异吗?何时使用其中一个?

    它们看起来很相似:

    # 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]
    
    3 回复  |  直到 7 年前
        1
  •  4
  •   Bogumił Kamiński    7 年前

    想想 NamedTuple 作为匿名者 struct 在朱丽亚中,不是 Dict . 尤其是在 命名元组 类型稳定。

    请注意,这也是Python和Julia在思维上的一个主要区别。在Julia中,如果您希望您的代码很快,您通常关心类型推断。

        2
  •  5
  •   dberge    7 年前

    Julia中的一个显著区别是,namedDuple是它自己的类型,因此编译器可以专门处理特定的命名元组签名,而dictionary方法必须从键中查找值。此外,一个namedDuple的每个值本身可以是一个不同的类型,允许进一步的优化和类型稳定性,而不仅仅是在字典中可以实现的。如果我们更进一步地修改它,使字典的类型是异构的,因此它是类型 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
    

    另一方面,namedDuple可以是类型稳定的。因为字段是由函数知道的,所以类型也被认为是 Float64 .

    @code_warntype foo(nt)
    
    Body::Float64
    4 1 ─ %1 = (Base.getfield)(x, :k2)::Float64                                                                                                                                                                                     │╻ getindex
      └──      return %1
    
        3
  •  -2
  •   Antonello    7 年前
    推荐文章