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