This is extremely likely to be a duplicate of something, but my serach foo is failing me.
It is known that tuples are immutable, so you can't really change them. Sometimes, however, it comes in handy to do something to the effect of changing, say, (1, 2, "three")
to (1, 2, 3)
, perhaps in a similar vein to the Haskell record update syntax. You wouldn't actually change the original tuple, but you'd get a new one that differs in just one (or more) elements.
A way to go about doing this would be:
elements = list(old_tuple)
elements[-1] = do_things_to(elements[-1])
new_tuple = tuple(elements)
I feel that changing a tuple to a list however kind of defeats the purpose of using the tuple type for old_tuple
to begin with: if you were using a list instead, you wouldn't have had to build a throw-away list copy of the tuple in memory per operation.
If you were to change, say, just the 3rd element of a tuple, you could also do this:
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)
This would resist changes in the number of elements in the tuple better than the naive approach:
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
...but it doesn't work if what you wanted to change was the last, or the n-th to last element. It also creates a throw away list (others
). It also forces you to name all elements up to the n-th.
Is there a better way?