frans frans - 2 months ago 8
Python Question

generate a modified copy of a tuple

I know I can't modify a tuple and I've seen ways to create a tuple from another one concatenating parts of the original manually like here.

But wonder whether there has emerged some pythonic way to 'modify' a tuple by implicitly creating a new one like

>>> source_tuple = ('this', 'is', 'the', 'old', 'tuple')
>>> new_tuple = source_tuple.replace(3, 'new')
>>> new_tuple
('this', 'is', 'the', 'new', 'tuple')


A possible implementation could look like this but I'm looking for a built in solution:

def replace_at(source, index, value):
if isinstance(source, tuple):
return source[:index] + (value,) + source[index + 1:]
elif isinstance(source, list):
return source[:index] + [value,] + source[index + 1:]
else:
explode()


it's not much work to implement such a functionality but like the
Enum
has demonstrated it's sometimes better to have an implementation everyone uses..

Edit: my goal is not to replace the source tuple. I know I could use lists but even in this case I would make a copy first. So I'm really just looking for a way to create a modified copy.

Answer

You can use a slice on the tuple (which yields a new tuple) and concatenate:

>>> x=3
>>> new_tuple=source_tuple[0:x]+('new',)+source_tuple[x+1:]
>>> new_tuple
('this', 'is', 'the', 'new', 'tuple')

Which you can then support either a list or tuple like so:

>>> def replace_at(source, index, value):
...     return source[0:index]+type(source)((value,))+source[index+1:]
...
>>> replace_at([1,2,3],1,'new')
[1, 'new', 3]
>>> replace_at((1,2,3),1,'new')
(1, 'new', 3)

Or, just do it directly on a list:

>>> source_tuple = ('this', 'is', 'the', 'old', 'tuple')
>>> li=list(source_tuple)
>>> li[3]='new'
>>> new_tuple=tuple(li)
>>> new_tuple
('this', 'is', 'the', 'new', 'tuple')

As stated in the comments -- that is what lists are for...

Comments