Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

0 views
Skip to first unread message

Gerrit Holl

unread,
Mar 12, 2003, 8:02:39 AM3/12/03
to
Guido van Rossum wrote in Python-Dev:
> Tuples are for heterogeneous data, list are for homogeneous data.
> Tuples are *not* read-only lists.

This makes me wonder.

FAQ entry 6.15 states:

> 6.15. Why are there separate tuple and list data types?
> This is done so that tuples can be immutable while lists are mutable.

I don't understand. Doesn't this FAQ entry mean that tuples are read-only
lists? Why are tuples not read-only lists? Lists are for homogeneous data?
Well, [0, None, "twelve"] is perfectly legal, of course, so what does this
mean? I'm curious!

yours,
Gerrit.

--
Asperger Syndroom - een persoonlijke benadering:
http://people.nl.linux.org/~gerrit/
Het zijn tijden om je zelf met politiek te bemoeien:
http://www.sp.nl/

Thomas Wouters

unread,
Mar 12, 2003, 8:56:23 AM3/12/03
to
On Wed, Mar 12, 2003 at 02:02:39PM +0100, Gerrit Holl wrote:
> Guido van Rossum wrote in Python-Dev:
> > Tuples are for heterogeneous data, list are for homogeneous data.
> > Tuples are *not* read-only lists.

> This makes me wonder.

Yes, taking Guido too seriously can have that effect on people <1.1 wink>
The trick is in knowing when Guido is proscribing dogmatic law, and when he
is describing his intent when he designed feature(tte)s of Python, or his
point of view at this moment, or how he wished people would see it, or
reacting to what he had for lunch. He's just human, you know, and no more
infallible than the best of us.

I think it may be safer for the general populace (and healthier for their
faith in Python) if Guido would post under a pseudonym instead :)

--
Thomas Wouters <tho...@xs4all.net>

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

Karl A. Krueger

unread,
Mar 12, 2003, 1:18:42 PM3/12/03
to
Gerrit Holl <ger...@nl.linux.org> wrote:
> Guido van Rossum wrote in Python-Dev:
>> Tuples are for heterogeneous data, list are for homogeneous data.
>> Tuples are *not* read-only lists.
>
> This makes me wonder.
>
> FAQ entry 6.15 states:
>
>> 6.15. Why are there separate tuple and list data types?
>> This is done so that tuples can be immutable while lists are mutable.
>
> I don't understand. Doesn't this FAQ entry mean that tuples are read-only
> lists? Why are tuples not read-only lists? Lists are for homogeneous data?
> Well, [0, None, "twelve"] is perfectly legal, of course, so what does this
> mean? I'm curious!

Delurking to speculate on this one ...

Tuples are more "struct-ish" than lists are, and represent a single
"structured" value, even though they have multiple data elements.

The Python library seems to use tuples in places where C would use
structs -- to represent records which encompass multiple pieces of data
but are still being used as a single value. The example of the 9-tuple
returned by time.localtime has been mentioned elsewhere -- even though
there are nine pieces of data there, in some sense it represents only
one value, namely a time.

Similarly, a Cartesian coordinate pair (x, y) is a single value even
though it has two data elements. This is a natural tuple.

Since a tuple represents a single value, it often makes sense to use it
as a dictionary key. You can only use an object as a dictionary key if
you know it is not going to get changed in-place, because that would
invalidate the hashing of the key. For instance, suppose we could do
this:

pt = (1, 2)
point_names = { pt: "The Park" }
pt[1] = 3 # pt is now (1, 3)

What should locations[pt] yield? Since pt and the first key of the
point_names dictionary both refer to the same place in memory (that is,
"pt is point_names.keys()[0]" is true), altering the value of pt[1]
would alter the value of the key in the dictionary! That would break
the dictionary's hashing, which would be bogus.

In short, since everything is a reference, if tuples are going to be
usefully hashable they have to be immutable.

Lists do not conceptually represent a single value; they represent a
sequence of values. As such, it makes sense to do things like add and
remove values in-place, which would not make much sense on a tuple. (To
add a value to a tuple would be to change its structure.)

What is meant by "tuples are for heterogeneous data, lists are for
homogeneous data", I suspect, is not that you can't put different data
types in a list. It is that the usual thing to do with a list is
iterate over it, executing the same operations on each element. This is
not the usual thing to do with a tuple -- you would not usually iterate
over the elements of the time 9-tuple, doing the same operation to all
of them, since they mean different things.

So, in short, lists are sequences of values whereas tuples are complex
values.

--
Karl A. Krueger <kkru...@example.edu>
Woods Hole Oceanographic Institution
Email address is spamtrapped. s/example/whoi/
"Outlook not so good." -- Magic 8-Ball Software Reviews

Nicola Larosa

unread,
Mar 12, 2003, 6:02:29 PM3/12/03
to
[WARNING: pet peeve ahead]

> FAQ entry 6.15 states:
>
>> 6.15. Why are there separate tuple and list data types?
>> This is done so that tuples can be immutable while lists are
>> mutable.

There's more than that. The tutorial states:

"Tuples have many uses. For example: (x, y) coordinate pairs, employee
records from a database, etc."

http://www.python.org/doc/2.3a2/tut/node7.html#SECTION007300000000000000000

I was using MySQLdb, and naturally enough, it returns tuples. I built
another tuple with the values from one field for a number of records,
and I wanted the index of the record with a particular value, so I
reached for a tuple.index() method, and guess what? There is no such
thing. :^(

I went to Google and searched through c.l.py., and to my
disappointment, found these discussions:

PROP: tuple.index(), tuple.count()
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&th=db5333ec65d2262c&rnum=1

How come tuples don't have an index method?
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&safe=off&th=99a50502426e8be5&rnum=1

which led to this Tracker entry:

[ 403693 ] tupleobject.c: implement tuple.index() and tuple.count()
http://sourceforge.net/tracker/?group_id=5470&atid=305470&func=detail&aid=403693

Date: 2001-02-15 05:49
Sender: gvanrossum
"Why bother? I like the fact that when you want to do list-ish
things you have to use lists. Use list(t).count(x) if you really
want this for a tuple.

"I'm rejecting this in the name of all those users who want Python
to be small."

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.

It's bad enough to be chided by Lua aficionados because they need just
one type to do what we do with tuples, lists and dictionaries. ;^) We
need no more superflous subtleties.

And no, list(t).index(x) does not qualify. Neither does
operator.indexOf() .

Guido, can't we settle this once and for all?

sism...@hebmex.com

unread,
Mar 12, 2003, 6:17:13 PM3/12/03
to
>
> 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.
>

But, for many others (myself included), tuples as they are make
perfect sense, in that they are not lists, are not for data
manipulation/querying, but for storage or association.

A tuple is a unit; it's not a collection of it's contents,
it's something else. So, tuples shouldn't have all of
list's read-only methods and attributes.

>
> It's bad enough to be chided by Lua aficionados because they need just
> one type to do what we do with tuples, lists and dictionaries. ;^) We
> need no more superflous subtleties.
>

"Chided by Lua aficionados"?
"Superfluous Subtleties"?

Sounds like you're trying to make Python more Lua-like. Not to
be insulting or disrespectful, but frankly, Lua stinks. It's
like Javascript-only-different (argh).

So Lua has a hyper-tuple-array-dictionary-from-hell, wow, nice.
What happens when you need true list semantics? Or a real
dictionary? Or you need to index by compound keys (aka, tuples)?

I had a look at Lua a few months ago, I didn't like it one bit.
But then, that's just me.

If "Lua Aficionados" chide you for "playing" with other languages,
maybe the problem isn't the other language, maybe the solution isn't
in mutating Python into Luaython.

>
> And no, list(t).index(x) does not qualify. Neither does
> operator.indexOf() .
>

Well, it does, if you're collecting data inside a tuple,
instead of using a list.

>
> Guido, can't we settle this once and for all?
>

I thought it was already settled.

-gus

Thomas Wouters

unread,
Mar 12, 2003, 7:36:10 PM3/12/03
to
On Thu, Mar 13, 2003 at 01:22:23AM +0100, Thomas Wouters wrote:

> Lists, on the other hand, convey the meaning of 'a set[*] of items'

[*] not 'set' in the mathematical meaning, just joe-user english.

Thomas Wouters

unread,
Mar 12, 2003, 7:22:23 PM3/12/03
to
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 a
light-weight, immutable object type than an actual list type; they're for
binding values closely together, as a single object. They convey a different
meaning to the reader of the program (or caller of a function): these value
are a single item (a response, an input parameter, a hostname and port, an
encoder/decoder pair) that consists of a (usually fixed) number of separate
items, and not necessarily of the same type. Related, but not welded
together. A port without the hostname is different information; you usually
need the hostname to make sense of the port at all. Et cetera.

Lists, on the other hand, convey the meaning of 'a set[*] of items', not
necessarily related in any way. A list of hostnames, for instance, could
well be built up out of just hostnames in string form or of tuples of
(hostname, port), and the hostnames could well be related by being in the
same domain, but you don't need one element of the list to make sense of the
other element.

Hence Guido's comment. If you have the need for a .count or .index method
for tuples, you are almost certainly using tuples the wrong way. No one is
going to stop you from writing a function to do the same thing on the
tuples, but the builtin datatype isn't going to change to accomodate misuse
of it.

> Guido, can't we settle this once and for all?

He already did, that's why the patch is rejected.

He-just-didn't-settle-it-the-way-you-want-<wink>'ly y'rs

Lulu of the Lotus-Eaters

unread,
Mar 13, 2003, 12:22:03 AM3/13/03
to
google...@tekNico.net (Nicola Larosa) wrote previously:

|Date: 2001-02-15 05:49 Sender: gvanrossum
|"Why bother? I like the fact that when you want to do list-ish
|things you have to use lists. Use list(t).count(x) if you really
|want this for a tuple.
|"I'm rejecting this in the name of all those users who want Python
|to be small."

|Guido, can't we settle this once and for all?

Sure looks to me like it HAS BEEN settled once and for all :-).

Tuples don't have an .count() method... so it is written, and so shall
it be (unless it changes in a later version).

Yours, David...

--
---[ to our friends at TLAs (spread the word) ]--------------------------
Echelon North Korea Nazi cracking spy smuggle Columbia fissionable Stego
White Water strategic Clinton Delta Force militia TEMPEST Libya Mossad
---[ Postmodern Enterprises <me...@gnosis.cx> ]--------------------------


Alex Martelli

unread,
Mar 13, 2003, 3:39:21 AM3/13/03
to
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".

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).

But as long as tuples are the one and only way to "use a list as a
dict key" &c, the theoretical arguments about tuples not being just
frozen lists are countered by too much practical baggage, IMHO.


Alex

Thomas Wouters

unread,
Mar 13, 2003, 4:29:12 AM3/13/03
to
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,

Alex Martelli

unread,
Mar 13, 2003, 6:07:09 AM3/13/03
to
On Thursday 13 March 2003 10:29 am, Thomas Wouters wrote:
...

> "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

Exactly the kinds of questions that Python lets me *AVOID* for most
other similar design situations. Python is mostly set up to encourage
avoidance of the "big design up front" fallacy -- wasting a lot of time
to determine how you may/will use something as development proceeds.


> 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.

Wrong! My experience tells me that's definitely NOT the way to get
changes into Python -- you work your ass off, then Guido rejects your
work. Putting about ideas for change, and hoping Guido picks them up
and convinces himself they're HIS ideas, is by far more productive,
whether you then do some of the detailed implementation work yourself
(often advisable, because if nobody does the work then of course the
change doesn't get into Python).

For example, when I first met Python in 1999 I posted a few ideas I
had about enhancements which I'd love to get into Python. One did
happen to coincide with an idea which Guido DID already have -- a
special method __contains__ to let you overload tests such as
"if x in y:" (I even proposed the same magic name he already had
in mind). Another was "new and revolutionary":

"""
Regarding the
for a in X:
case, the point is that I can well have a class X [...] where I can easily
get the "next" item, but not the "N-th item" for arbitrary N without a
large amount of work.
...
The way I envision this -- if X chooses to implement a method __enum__,
then, that method must return an object which implements methods
such as __current__ (returning the current element in the iteration) and
__advance__ (returning false if at end, else stepping forward) --
"""

In this case, the method ended up being named __iter__ instead of
__enum__ as I had proposed, and the returned object implements a
single method with a non-magic name 'next' that steps forward _and_
also returns the resulting element in the iteration, rather than two magic-
named methods to perform the two tasks. But "to start work on it" was
MOST definitely not the way to "get this into Python" -- _that_ would
most likely have been a total waste of effort. Far better to get the idea
into the air and hope that somebody in the right place breathes it.


The __as_immutable__ and __as_temporarily_immutable__ methods
in Python's 2.3 sets.py's Set class are perhaps a start. I think that the
next step is gaining a consensus about such methods being useful not
just to have sets (in their immutable versions) as members of other
sets, but also for (e.g.) lists as members of sets. And for that purpose,
I think that no "start work on it" is any earthly use -- the pen is mightier
than the code. We'll see...


Alex


Thomas Wouters

unread,
Mar 13, 2003, 7:20:20 AM3/13/03
to
On Thu, Mar 13, 2003 at 12:07:09PM +0100, Alex Martelli wrote:
> On Thursday 13 March 2003 10:29 am, Thomas Wouters wrote:
> ...
> > "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

> Exactly the kinds of questions that Python lets me *AVOID* for most
> other similar design situations. Python is mostly set up to encourage
> avoidance of the "big design up front" fallacy -- wasting a lot of time
> to determine how you may/will use something as development proceeds.

I'm not sure whether that debunks or proves my point, as in my example I
throw away (part of) the design I already had.

> > 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.
>
> Wrong! My experience tells me that's definitely NOT the way to get
> changes into Python -- you work your ass off, then Guido rejects your
> work.

Notice how I said it didn't require modification of the interpreter or of
builtin types; *that* kind of work can get rejected by Guido. A separate
module to accomplish a task is never wasted, as long as it's useful (and if
it's not useful, it shouldn't be added, right?) There are plenty of examples
for that: Cookie, email, bsddb3, even Zope's ExtensionClass to some extent.
And some, if not most, of the new modules that got written with the chief
intent of adding it to the stdlib (sets, for example, and email again) had
a lot of prior art to work with (or someone who was willing to dog Guido for
hours each day, like heapq<wink>)

> For example, when I first met Python in 1999 I posted a few ideas

[ on iteration, which was rejected and later added as __iter__ ]

Not quite an analogous example. The iteration protocol requires interpreter
changes to be generally useful, as having to write 'for item in
iterator(object)' or 'for item in object.iterator()' almost negates the
purpose of having it. And I don't remember exactly how iterators came to be,
but I believe it had much to do with Tim Peters writing a simple
iterator/generator patch and showing Guido some example code, saying "Look
how Pythonic you think this looks." I'm sure Tim can shed some light on
that ;)

> The __as_immutable__ and __as_temporarily_immutable__ methods
> in Python's 2.3 sets.py's Set class are perhaps a start. I think that the
> next step is gaining a consensus about such methods being useful not
> just to have sets (in their immutable versions) as members of other
> sets, but also for (e.g.) lists as members of sets. And for that purpose,
> I think that no "start work on it" is any earthly use -- the pen is mightier
> than the code. We'll see...

Yes, PR is as important in selling an idea to Guido (or most people, in
fact) as code is. But *without* code, it becomes that much harder to sell,
even if it's just half-working, proof-of-concept, pseudo-code. And nothing
makes accepting more easy than having a working, community-accepted,
widely-used implementation ready and working. :-)

Alex Martelli

unread,
Mar 13, 2003, 1:05:23 PM3/13/03
to
On Thursday 13 March 2003 01:20 pm, Thomas Wouters wrote:
...

> Notice how I said it didn't require modification of the interpreter or of
> builtin types; *that* kind of work can get rejected by Guido. A separate
> module to accomplish a task is never wasted, as long as it's useful (and if
> it's not useful, it shouldn't be added, right?) There are plenty of

Kludges to work around the lack of __as_immutable__ in built-in lists &c
would make near-useless any "separate module to accomplish the task"
of using (frozen copies of) lists as dict keys &c -- just as:

> Not quite an analogous example. The iteration protocol requires interpreter
> changes to be generally useful, as having to write 'for item in
> iterator(object)' or 'for item in object.iterator()' almost negates the

What makes you think that having to do somedict[freeze(somelist)]=xx and
then check by "if tempfreeze(somelist) in somedict:" etc would be any
more "generally useful" than having to write "for item in iter(x):" ...?


> Yes, PR is as important in selling an idea to Guido (or most people, in
> fact) as code is. But *without* code, it becomes that much harder to sell,
> even if it's just half-working, proof-of-concept, pseudo-code. And nothing
> makes accepting more easy than having a working, community-accepted,
> widely-used implementation ready and working. :-)

There is ZERO chance of having a "community-accepted implementation"
for something that needs to be in the core to be useful -- and this holds for
a "freezing protocol" just as much as it holds for iterator. When the needed
changes are obvious (and that is clearly so for "freezing", even more than
for iterators), developing a patch to implement the obvious is a
just-as-obvious utter waste of time and energy that (if one IS keen to have
the change in the core) should instead be entirely deployed in "PR work".

Do you think that it makes ANY difference whether there's one or a million
patches to implement ternary operators -- will the existence of those patches
make ANY difference to the likelihood of Guido introducing a ternary op into
Python?! *PAH*. It's *STRICTLY* a matter of creating an upswell of popular
support -=- enough to get Guido to decide to hold a popular consultive vote
on the issue, AND enough to get (hypothetically) overwhelming support for
the change. Ternary proponents managed the first but not the second --
we'll see what happens. But NO MATTER how many patches they might
have written, all of them together would have been completely useless in
swinging a single popular vote, and thus a total waste of effort.

I think you're confusing the issue of changes that appear to present any
amount at all of technical difficulty, with that of changes which are entirely
obvious and bereft of any difficulty EXCEPT that of convincing Guido.

Working to develop patches is just as obviously "utterly useless" for the
latter kind, as it's "potentially useful" for the former kind. And since a
"freezing protocol" is quite clearly in the latter category, thus do I believe
that your advice in the matter is totally wrong, misplaced, and misleading.


Alex


Tim Peters

unread,
Mar 14, 2003, 12:06:25 AM3/14/03
to
[Thomas Wouters]
> ...

> 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.

That hack wasn't obnoxious enough, and the internal immutable list type
doesn't exist in 2.3 anymore. The problem was that, e.g., in

mutator = alist.append
alist.sort()

mutator was bound to the append method of the mutable view of the list, and
if comarison invoked mutator, a segfault could result despite all the
immutable list hair (alist.append() raises an exception during the sort
because the immutable view's append method gets invoked; capturing mutator
before the sort yields a bound method that doesn't know squat about the
immutable view).

Armin Rigo dreamt up a smaller and meaner hack that's currently thought to
be bulletproof. It has the peculiar property of making a list appear to be
empty *during* sorting:

C:\Code\python\PCbuild>python
Python 2.3a2+ ...
>>> def c(x, y):
... print "len(list) =", len(list)
... return cmp(x, y)
...
>>> list = range(2)
>>> list.sort(c)
len(list) = 0
>>>

It also reliably complains if any attempt to mutate the list is made during
the sort:

>>> def d(x, y):
... list.append(2)
... return cmp(x, y)
...
>>> list.sort(d)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: list modified during sort
>>>

In fact, it doesn't stop mutations at all, or even try to! It lets them
happen, but to temp list memory that exists only during the sort. The
mutation is actually detected after the sort completes. Let's see someone
try to generalize that into a feature <winK>.


0 new messages