Tuples, what are they: read-only lists or heterogeneous data arrays?

Thomas Wouters thomas at xs4all.net
Thu Mar 13 04:29:12 EST 2003


On Thu, Mar 13, 2003 at 08:39:21AM +0000, Alex Martelli wrote:
> Thomas Wouters wrote:

> > On Wed, Mar 12, 2003 at 03:02:29PM -0800, Nicola Larosa wrote:

> > [ Guido rejects the 'add-list-methods-to-tuples' patch ]

> >> Sorry, but this makes no sense. I entirely support the notion that a
> >> tuple should be *exactly* like a list, apart from the fact that it is
> >> immutable, so every read-only list method should be available for
> >> tuples, too.

> > You must have missed the posting that started this thread. Tuples *are
> > not* lists, and should not be used as 'read-only lists' for the sake of
> > having a read-only list or for the sake of performance. Tuples are more of

> So what would you propose to do, when somebody needs to use a list as
> a key into a dictionary -- a list that's not going to be subject to any
> more changes, but will often need to be subject to non-mutating method
> calls such as .count ?  Peppering the code with type conversion calls
> tuple(this) and list(that) is then a serious violation of the idea that
> "practicality beats purity".

"Practicality" isn't just about how hard it is to write a certain operation
or protocol or algorithm or practice, it's also about how common that
practice is. How often has the above happened to you ? I've never had the
need for it, but if I had, I could think of a half dozen ways to fix it.
Some examples:


    def tup_index(t, v):
        return list(t).index(v)
    def tup_count(t, v):
        return list(t).count(v)

    class HashableList(list):
        def __hash__(self):
            return hash(tuple(self))

    class MethodedTuple(tuple):
        def count(self, v):
            return list(self).count(v)
        def index(self, v):
            return list(self).index(v)

    class ConvertingDict(dict):
        def __getitem__(self, k):
            if isinstance(k, list):
                k = tuple(k)
            return dict.__getitem__(self, k)
        def __setitem__(self, k, v):
            if isinstance(k, list):
                k = tuple(k)
            return dict.__getitem__(self, k, v)

    class ImmutableList(list):
        ...

    class CustomDataType:
        ...

(I'd probably go with the last one, myself, depending on the exact nature of
the list-as-a-dict-key, but notice how short and elegant most of them are. :)
What is more practical, keeping the language compact and distinct or
catering to every possible one-liner ? I like Python not just because it's a
terrific language with great clarity of purpose and a fine community, but
also because it makes me think about my code by warning me when I'm doing
something wrong.

"Wait, I need to use an unwieldy large list/tuple as a dict key, but I also
want to count/index it... Do I really want the whole list as the dict key,
or just a few key elements ? What if I add elements later ?" and depending
on that go "I'll use a count/index function / a list/tuple subclass" or
"This should probably be a separate class instead, with clearly named
attributes and methods. Yay, Pythoooon, for reminding me before I forget
what this code was supposed to do!"

> If tuples are NOT to be used as "frozen lists" for such purposes as
> indexing into a dictionary, putting into a set, and so on, then we need
> a separate way to "freeze a list" (or "get a frozen equivalent of a
> list", that would be fine too) -- perhaps along the same lines by which
> sets can be "frozen" into immutable-sets in the sets.py module.  I think
> it might be a very nice addition (particularly if done via a protocol
> that also applied to dicts and that users could implement for their own
> classes if they wish to).

Well, there is a C type 'immutable list', but its support is incomplete,
it's not exported to Python and you don't really want to use it other than
for its original (and still current, I believe) purpose of defying __cmp__
methods that mutate the list being sorted. Creating an immutable list type
shouldn't be too hard now, though, or you can implement it in C based on the
existing immutable type. It requires no interpreter or builtin-types
changes, but could of course be added to the stdlib. If you want a
'frozen-copy' protocol for mutable objects, there's only one way to get it:
start work on it.

And-I-know-*you*-know-that-Alex--I'm-clarifying-for-the-readers<wink>'ly y'rs,
-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me spread!





More information about the Python-list mailing list