Julia 修改复制元组

Julia 修改复制元组,julia,Julia,我有一个元组: my_tup=(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9) 我想修改这个元组中的一个值。因为元组是不可变的,所以明显的路径不起作用: my_tup[:a]=50 #Raises an error, as expected 因此,为了执行修改,我想在更改目标元素的同时复制元组及其元素 我目前的解决办法如下: my_tup=(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9) args = keys(my_tup) NamedT

我有一个元组:

my_tup=(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9)
我想修改这个元组中的一个值。因为元组是不可变的,所以明显的路径不起作用:

my_tup[:a]=50 #Raises an error, as expected
因此,为了执行修改,我想在更改目标元素的同时复制元组及其元素

我目前的解决办法如下:

my_tup=(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9)
args = keys(my_tup)
NamedTuple{args}(i!=:a ? getfield(my_tup, i) : 50 for i in args)
但是这看起来很冗长,或者在标准库中应该已经有了一个函数

有更好的方法吗?

您可以使用两个命名元组:

julia> xs = (a = 1, b = 2, c = 3)
(a = 1, b = 2, c = 3)

julia> ys = merge(xs, (; a = 50))
(a = 50, b = 2, c = 3)

David Varela给出了正确的答案,“使用
合并
”。这是一项重要的技术

  • 为了使此解决方案更容易提供给其他人,下面是一些示例
创建普通元组(未命名元组)和命名元组

julia> namedtuple = (a = 1, b = 2, c = 3);  # the initial NamedTuple
julia> changes_to_make = (b = 0 ,);         # the modifications intended

julia> changed_namedtuple = merge(namedtuple, changes_to_make)
(a = 1, b = 0, c = 3)
元组和命名元组均使用括号构造:

julia> a_tuple = (1, 2)
(1, 2)

julia> a_namedtuple = (a = 1, b = 2)
(a = 1, b = 2)
如果我们试图以同样的方式构造一个元组或NamedTuple,并且只包含一个条目,那么它就不起作用;相反,这些值是直接分配给命名变量的

julia> not_a_tuple = ("xyz");
julia> not_a_tuple, typeof(not_a_tuple)
("xyz", String)

julia> not_a_namedtuple = (abc = "xyz");
julia> not_a_namedtuple, typeof(not_a_namedtuple)
("xyz", String)
为了构造具有单个值的元组和命名元组,我们让Julia知道我们正在使用[命名]元组。一个简单的方法是在右括号前加一个逗号“,”,这个方法对两种元组都适用。对于视觉强调,我将逗号与值分开;在源代码中不必这样做

julia> a_tuple = (0.5 ,)
(0.5,)

julia> a_namedtuple = (onehalf = 0.5 ,)
(onehalf = 0.5,)
替换NamedTuples中的值时

julia> namedtuple = (a = 1, b = 2, c = 3);  # the initial NamedTuple
julia> changes_to_make = (b = 0 ,);         # the modifications intended

julia> changed_namedtuple = merge(namedtuple, changes_to_make)
(a = 1, b = 0, c = 3)

为什么当我做
(my_tup…,)
时,名称会被删除,但使用
(my_tup…,a=50)
时,名称会被保留?嗨,这就是名元组的
iter
定义方式<代码>(my\u tup…,)
与my\u tup中xxx的
行为相匹配。要复制而不修改,请使用
(;my_tup…
注意,使用
合并
还可以执行“动态”合并:
合并(xs,[:c=>4])
,这有时很有用。
julia> my_tup=(a=1,b=2,c=3,d=4,e=5,f=6,g=7,h=8,i=9)
(a = 1, b = 2, c = 3,d = 4, e = 5, f = 6, g = 7, h = 8, i = 9)

julia> new_one = (my_tup..., a=50)
(a = 50, b = 2, c = 3, d = 4, e = 5, f = 6, g = 7, h = 8, i = 9)