More pythonic way to change an element of a tuple?
Jeff Epler
jepler at unpythonic.net
Wed Nov 27 13:22:19 EST 2002
On Wed, Nov 27, 2002 at 09:58:44AM -0800, Richard Muller wrote:
> I frequently have to change a single element of a tuple, and I wind up
> doing something like this:
Then you should probably ask yourself why you're using a tuple.*
Otherwise, toss it in a function and forget about the complexity.
def mutate_tuple(t, i, v):
t = list(t)
t[i] = v
return tuple(t)
def increment_tuple_item(t, i):
return mutate_tuple(t, i, t[i]+1)
data_in_tuple = increment_tuple_item(data_in_tuple, item)
If you want to index a dict by these things, then why not make your
"dict" a subclass of dict and use lists?
class my_dict(dict):
def __getitem__(self, i):
if isinstance(i, list): i = tuple(i)
return dict.__getitem__(i)
def __setitem__(self, i, v):
if isinstance(i, list): i = tuple(i)
return dict.__setitem__(i, v)
[and so on for other methods you care about]
Of course, if you "mutate" your "tuples" less frequently than you access
the dict with them, this will likely be slower, since you have the
tuple() call once per get/set, instead of once per "mutate".
You could also hide this in a class.
class MutableTuple:
def __init__(self, t): self.t = t
# Set up minimum code to act as a dict key
def __hash__(self): return hash(self.t)
def __cmp__(self, other): return cmp(self.t, other)
# And the method to mutate
def inc(self, i):
self.t = increment_tuple_item(self.t, i)
Now, if you have mt = MutableTuple(...), you can index a dict by it
>>> d = {(1,2,3): 1, (1,2,4): 0}
>>> mt = MutableTuple((1,2,3))
>>> print d[mt]
1
>>> mt.inc(2)
>>> print d[mt]
0
and you can use mt.t as a key when setting/changing dictionary keys:
>>> d[mt.t] = 2
>>> print d
{(1, 2, 3): 1, (1, 2, 4): 2}
>>> print d[mt]
2
Jeff
More information about the Python-list
mailing list