tuples, index method, Python's design

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Wed Apr 11 08:49:22 EDT 2007


On Wed, 11 Apr 2007 08:57:43 +0200, Hendrik van Rooyen wrote:

> I can write:
> 
> L = [a,b,c,d,e,f]
> T= (a,b,c,d,e,f)
> 
> The difference between the two things is that I can add to 
> and change L, but not T.

No, that's *one* difference between the two things. There are other
differences, e.g. the obvious is that they are different types (and
therefore different string representations), but also some not so obvious:

>>> hash((1,2,3))
-378539185

>>> hash([1,2,3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable



> Now it seems to me that whatever argument is used to justify the
> existence of:
> 
> n = L.index(d)
> 
> can be used to justify the existence of:
> 
> n = T.index(d)
> 
> and vice versa.

That depends on what you the purpose of lists and tuples are. Yes, they
are both sequences, but they have different uses. Ball-peen hammers and
tack hammers are both hammers, but they have different purposes and
therefore different functionality. Likewise for tuples and lists:

Lists are designed for sequences of homogeneous items, e.g.:

L = [1, 2, 4, 8, 16, 32]

while tuples are designed to be more like structs or records, with
heterogeneous items, e.g.:

T = ("Fred", 32, 12.789, {}, None, '\t')

So according to these intended usages, it makes sense to ask for
L.index(32) because in an application you have no way of telling which
item (if any) 32 would be in. But T.index(32) is seen as meaningless,
because you know that either 32 is in the second slot or it isn't --
you're never going to find yourself in a situation knowing that 32 is
*somewhere* in the tuple without knowing where the one place it *could* be.

(There is one other option: you care that 32 is somewhere in the tuple,
but you don't care where. That's when you use the "in" operator.)

Anyway, that was the original design. When you see tuple, think struct. If
you have a struct, it doesn't make a whole lot of sense to ask "which
field contains 32?", and so according to this intended usage, giving
tuples index and count methods would be a Bad Idea: it just makes extra
work for the Python Dev team, for no benefit.

Personally, I think that tuples do double-duty as *both* immutable lists
and structs/records. So even though index and count methods don't make
sense for a struct, it does make sense for an immutable list, and I for
one would not object to seeing tuples grow those two methods.

[snip]


> And I would heretically go even further, and argue that it should be
> possible to write stuff like:
> 
> T = T.append(x)
> 
> And get back a new tuple bound to the old name...

That's a design decision, and one that's not likely to be accepted because
it's so easy to do:


T = T + (x,)          # like T.append()
T = T + (x, y, z)     # like T.extend()
T = tuple(sorted(T))  # like T.sort()
T = T[:4] + T[4:]     # like del T[4]
etc.

It makes sense for lists to have these methods because lists can make the
changes in place, but tuples can't.



-- 
Steven.




More information about the Python-list mailing list