这很可能是一些东西的重复,但我的serach foo让我失望。什么是“改变”元组元素的优雅方式?
它是众所周知的元组是不可变的,所以你不能真的改变它们。然而,有时候,可能需要做一些改变的工作,比如(1, 2, "three")
到(1, 2, 3)
,或许与Haskell record update syntax.类似,但实际上并没有改变原始元组,但是你会得到一个新的只有一个(或更多)元素不同。
的一种方式去这样做,这将是:
elements = list(old_tuple)
elements[-1] = do_things_to(elements[-1])
new_tuple = tuple(elements)
我觉得改变一个元组列表,但是那种违背了使用的元组类型old_tuple
开始与目的:如果你是使用列表来代替,您不必在每个操作的内存中构建元组丢弃列表副本。
如果你要改变,比方说,只是一个元组的第三个元素,你也可以这样做:
def update_third_element(a, b, c, *others):
c = do_things_to(c)
return tuple(a, b, c, *others)
new_tuple = update_third_element(*old_tuple)
这将抵制在元组中的元素数量的变化比幼稚的做法更好:
a, b, c, d, e, f, g, h, i, j = old_tuple
c = do_things_to(c)
new_tuple = (a, b, c, d, e, f, g, h, j, j) # whoops
...但它不工作,如果你想改变是最后一个,或ñ列到最后一个元素。它还创建一个扔掉列表(others
)。它也迫使你命名所有元素,最多为n -th。
有没有更好的方法?
你说,“改变一个元组的列表但是那种违背了使用的元组类型的宗旨,为'old_tuple'到首先”。事实上,需要改变一个元素就是破坏了使用元组类型开始的目的。如果你发现自己需要改变元组的元素,他们可能不应该首先是元组。如果你不需要经常这样做,它可能会有点难看。 – BrenBarn
@BrenBarn我不同意不可变性(如果你持有这个对象的引用,它永远不会改变)意味着你不应该想要一个对象,并从中创建一个与原始对象略有不同的新对象。 – badp
对于那些不相信的人来说,这个最好的例子当然是'str's,它有一个'替换'的方法,尽管它是不可变的。 – badp