List vs tuples

M

Mitja

A neewbie's question here, probably discussed before:
what's the purpose of having both lists AND tuples?
At the first (and second and third, to be honest) glance lists are just
tuples with extended functionality, so why have tuples around?
I've been working with Python for a few months now but haven't yet come
across a problem that would really require tuples.

Thanks in advance,
Mitja
 
R

Roy Smith

"Mitja" <[email protected]> said:
A neewbie's question here, probably discussed before:
what's the purpose of having both lists AND tuples?
At the first (and second and third, to be honest) glance lists are just
tuples with extended functionality, so why have tuples around?
I've been working with Python for a few months now but haven't yet come
across a problem that would really require tuples.

Thanks in advance,
Mitja

The biggest reason that I can think of is that tuples are immutable, and
you need an immutable object to be a dictionary key.

Also, without knowing the details of how they are implemented, my guess
would be that tuples are more efficient, as a direct result of their
immutability.
 
J

John Roth

Mitja said:
A neewbie's question here, probably discussed before:
what's the purpose of having both lists AND tuples?
At the first (and second and third, to be honest) glance lists are just
tuples with extended functionality, so why have tuples around?
I've been working with Python for a few months now but haven't yet come
across a problem that would really require tuples.

It's a common question. A list is a data structure that is
intended to be used with homogenous members; that is,
with members of the same type.

You've probably used tuples without realizing it. For
example, the following idiom involves a tuple:

hours, minute, second = getTime()

where

def getTime(.....)
#some calc
return hour, minute, second

While it looks like return is returning multiple
objects, it actually isn't. It's returning one object:
a tuple of three elements which is then being
unpacked on the receiving end.

You could call the same routine this way as well:

result = getTime()

and result would be a tuple of three elements.

Another way of thinking about it is that you would
use a tuple the same way you would use a struct in
a language like C, if you didn't want to go to the trouble
of creating a full-fledged object for it.

John Roth
 
A

Andrei

Mitja wrote on Thu, 8 Apr 2004 18:47:07 +0200:
A neewbie's question here, probably discussed before:
what's the purpose of having both lists AND tuples?
At the first (and second and third, to be honest) glance lists are just
tuples with extended functionality, so why have tuples around?

You can use tuples as keys in a dictionary, but you can't use lists for
that purpose (because they're mutable).
I've been working with Python for a few months now but haven't yet come
across a problem that would really require tuples.

That's possible. Lists offer many more facilities than tuples (mainly due
to them being mutable), so it's easier to just use a list (even if a tuple
could do the job).

--
Yours,

Andrei

=====
Real contact info (decode with rot13):
(e-mail address removed). Fcnz-serr! Cyrnfr qb abg hfr va choyvp cbfgf. V ernq
gur yvfg, fb gurer'f ab arrq gb PP.
 
R

Roy Smith

John Roth said:
A list is a data structure that is intended to be used with
homogenous members; that is, with members of the same type.

There's really nothing about a list which makes it more suitable for
homogeneous elements than a tuple. It's true that people do tend to
think tuple when they want a mixed collection of objects, but there's
nothing in the language semantics which makes that so.

I've written lots of code which parses data files. If you've got a
sequence of arbitrary type objects, the easiest way to process them is
often to read them sequentially and append them to a list. I don't see
anything wrong with that. For example, I once had to write some code
which parsed SQL statements that looked something like:

insert into foo values (1, 2, 'foo', 3.14, 'bar', 4, 5, 'baz', ...);

There were a total of about 30 items of mixed type (strings, integers,
and floats) in the ()'s.

One of the really nice things about Python (vs. C++ or Java) is that
you're not bound by the tyranny of static typing. This is a perfect
example of how this makes life so simple.
 
J

John Roth

Roy Smith said:
There's really nothing about a list which makes it more suitable for
homogeneous elements than a tuple. It's true that people do tend to
think tuple when they want a mixed collection of objects, but there's
nothing in the language semantics which makes that so.

I've written lots of code which parses data files. If you've got a
sequence of arbitrary type objects, the easiest way to process them is
often to read them sequentially and append them to a list. I don't see
anything wrong with that. For example, I once had to write some code
which parsed SQL statements that looked something like:

insert into foo values (1, 2, 'foo', 3.14, 'bar', 4, 5, 'baz', ...);

There were a total of about 30 items of mixed type (strings, integers,
and floats) in the ()'s.

One of the really nice things about Python (vs. C++ or Java) is that
you're not bound by the tyranny of static typing. This is a perfect
example of how this makes life so simple.

This is perfectly true, but that's the intention. Guido says
so himself. Lots of people either don't believe him, or
don't understand him.

If you think of it this way, the "quirks" become understandable:
it makes no sense to append something to the end of a c type
struct, for example.

John Roth
 
D

Donn Cave

There's really nothing about a list which makes it more suitable for
homogeneous elements than a tuple. It's true that people do tend to
think tuple when they want a mixed collection of objects, but there's
nothing in the language semantics which makes that so.

I've written lots of code which parses data files. If you've got a
sequence of arbitrary type objects, the easiest way to process them is
often to read them sequentially and append them to a list. I don't see
anything wrong with that. For example, I once had to write some code
which parsed SQL statements that looked something like:

insert into foo values (1, 2, 'foo', 3.14, 'bar', 4, 5, 'baz', ...);

There were a total of about 30 items of mixed type (strings, integers,
and floats) in the ()'s.

One of the really nice things about Python (vs. C++ or Java) is that
you're not bound by the tyranny of static typing. This is a perfect
example of how this makes life so simple.

Oh no, here we go again.

In the hope that we can all get along, here's how
both of these arguments can be true. And I'm sure
Guido would agree if he were reading this, unless
he was in an unusually obtuse frame of mind.

Lists are indeed homogeneous by nature, but that
doesn't mean that each element has the same type
as the next. It means that any slice of the list
has the same "type" as any other slice.

When we are dealing with a record type, an ordered
collection of items where an item's meaning is
determined by its position, this obviously should
be a tuple. For example, the tm struct returned
from time.localtime(): each member is an integer,
but it's not homogeneous in the list sense - the
only valid slice of a tm value is [:], any other
slice is not a tm value, its type is different
even if it is still a tuple.

When we are dealing with a regular list, its type
is the same before and after you append() a new
element. That doesn't mean that the new element
is the same type as its predecessor, it just means
that the list isn't itself a new type now that it
has that last element.

Donn Cave, (e-mail address removed)
 
A

Arthur

It's a common question. A list is a data structure that is
intended to be used with homogenous members; that is,
with members of the same type.

As succeint and comforting as the explanation is....

I have consulted the Python Desgin Manual: Occult Edition, and if my
search of the list archives is true, the statement:

"""

A list is a data structure that is intended to be used with homogenous
members; that is,with members of the same type.

"""

is still 6 incantaions shy of becoming meaningful.

5 now actually.

Art
 
I

Isaac To

John> It's a common question. A list is a data structure that is
John> intended to be used with homogenous members; that is, with members
John> of the same type.

I feel you argument very strange. Even that it might be the original
intention, I see nothing in the language that support your argument.

In particular, nothing says that tuples cannot be used (or is troublesome to
use) when members are of the same type. And nothing says that lists cannot
be used (or is troublesome to use) when members are of different types.

John> You've probably used tuples without realizing it. For example, the
John> following idiom involves a tuple:

John> hours, minute, second = getTime()

John> where

John> def getTime(.....) #some calc return hour, minute, second

John> While it looks like return is returning multiple objects, it
John> actually isn't. It's returning one object: a tuple of three
John> elements which is then being unpacked on the receiving end.

If getTime() give you a list instead, then [hours, minute, second] =
getTime() would still give you the hours, minute and second variables
assigned.

John> You could call the same routine this way as well:

John> result = getTime()

John> and result would be a tuple of three elements.

And if getTime() give you a list of course result would be a list instead.
Nothing magic.

John> Another way of thinking about it is that you would use a tuple the
John> same way you would use a struct in a language like C, if you
John> didn't want to go to the trouble of creating a full-fledged object
John> for it.

And you can use a list here as well. Indeed, if you want to emulate C
struct, you probably will use list instead of tuples, since in C, structs
are mutable.

Regards,
Isaac.
 
J

John Roth

Isaac To said:
John> It's a common question. A list is a data structure that is
John> intended to be used with homogenous members; that is, with members
John> of the same type.

I feel you argument very strange. Even that it might be the original
intention, I see nothing in the language that support your argument.

Python is an extremely flexible and dynamic language. There's very
little specialized support for a lot of things. That doesn't mean that
the language designers didn't have that usage in mind.
In particular, nothing says that tuples cannot be used (or is troublesome to
use) when members are of the same type. And nothing says that lists cannot
be used (or is troublesome to use) when members are of different types.

Quite true. So what? Python, by design, does not get in your
way when you try to do strange and absurd things. For some
people in some situations, those things are undoubtedly going
to be the most obvious and reasonable way to approach their
problem.
If getTime() give you a list instead, then [hours, minute, second] =
getTime() would still give you the hours, minute and second variables
assigned.

True. Again, so what? The basic conceptual issue, which
Don Cave explained much better than I did, is that any
subsequence of a list is of the same *conceptual* type as the
list itself. A subset of the fields of a struct is not of the same
conceptual type as the original struct. You cannot take the
third element of that time tuple and claim it is the same type
(a time of day) as the original.
And you can use a list here as well. Indeed, if you want to emulate C
struct, you probably will use list instead of tuples, since in C, structs
are mutable.

By the time I want to actually change the elements, I'm going
to want a full fledged object where I can refer to the various
elements by name.

As far as I'm concerned, tuples serve a fairly well defined niche.
I don't think they're all that successful a language feature for a
number of reasons, among which are that I much prefer to deal
with struct-like constructs by name, not by index position, and
growing a tuple into an object is a rather messy proposition for
exactly that reason.

The other major issue here is that you seem to be trying
to argue that tuples are unnecessary because lists can do
everything that tuples can, and more (except be used as
keys in dicts, besides they take up more memory and
they're slower.)

I don't buy that line of arguement. A large part of programming
is finding ways of expressing intent in the program so you
don't wonder what you did six months later. Tuples and lists
serve such different conceptual issues that they help expressiveness.

John Roth
 
R

Roy Smith

Isaac To said:
And you can use a list here as well. Indeed, if you want to emulate C
struct, you probably will use list instead of tuples, since in C, structs
are mutable.

It's a bit of a misnomer to say that tuples (or lists) emulate C
structs. You access the elements of a struct by name, but you access
the elements of a tuple by index. A much better emulation of a C struct
is a degenerate class with no methods. If I wanted to emulate:

struct myData {
int x;
int y;
} datum = {1, 42};

I'd do something like:

class myData:
pass

datum = myData()
datum.x = 1
datum.y = 42

The reason people sometimes think of tuples as struct-like is because
they are often used to return multiple values from functions. To use
the example often cited, you might do:

x, y = getCoordinates()

where getCoordinates() returns a tuple of two numbers. It sort of looks
like a struct because it's got x an y "members", but the x and y names
are assigned in the unpacking operation, they're not inherent in the
object returned. A more "struct-like" way of doing it would be to have
getCoordinates() return something like the myData object shown above.
Then you'd have:

point = getCoordinates()

and you could make use of point.x and point.y in your code.

I'm not saying that the idea of returning a tuple and immediately
unpacking it isn't handy. It certainly is, and I use it often in the
code that I write. But, I think saying that it emulates a C struct
gives people the wrong idea of what's going on.
 
I

Isaac To

John> The other major issue here is that you seem to be trying to argue
John> that tuples are unnecessary because lists can do everything that
John> tuples can, and more (except be used as keys in dicts, besides
John> they take up more memory and they're slower.)

Far from the truth (how can you imply what I think by just reading one
message I post, and that message didn't says anything that you believe I
"think"). I just find it strange that to argue that tuples is for
"emulating structs", which can be done perfectly (or indeed better) using
lists instead.

John> I don't buy that line of arguement. A large part of programming is
John> finding ways of expressing intent in the program so you don't
John> wonder what you did six months later. Tuples and lists serve such
John> different conceptual issues that they help expressiveness.

If lists and tuples are exactly (or nearly) the same, just like class and
struct in C++, then I'll buy the argument. Then the distinction would
simply be documentary (I believe C++ struct and class distinction serves
important purposes, too). But the fact is, lists and tuples are not the
same. If I have a program using lists and I suddenly change all of them to
tuples, or if I have a program using tuples and I suddenly change all of
them to lists, my program breaks. And it breaks in a way that resolving it
would cause substantial performance and correctness issues. If I need a
struct-like object and because of your argument, I use tuples, I'll get
burnt later by having to change all of them to lists and deal with the
performance and correctness issues.

So I don't buy that line of thoughts. Lists is something that can change,
and tuples is something that can't change (at least, the references it holds
can't change; if you change a reference referred by this reference that's
another matter). I think this by itself serves a very clear documentary
purpose, than the (what I believe bogus) argument that tuples serves as
something like a struct. So tuples looks like a "value", just like a string
looks like a value in Python; while lists looks like a "variable", just like
a dictionary.

Regards,
Isaac.
 
U

urnerk

<posted & mailed>

Isaac said:
John> It's a common question. A list is a data structure that is
John> intended to be used with homogenous members; that is, with
members John> of the same type.

I feel you argument very strange. Even that it might be the original
intention, I see nothing in the language that support your argument.

In Python, lists don't care about members being homogenous. There's a
less-used array type for that, in the standard library. The principle
distinction between lists and tuples is indeed in the mutability
department.

As for emulating C structs, I liked the suggestion of using a class with
only data attributes. That's a logical analogy, as in C++, it's the struct
that morphs into the basic class, with the addition of methods to data.

However, if you really want to used a low level C struct, there's actually a
struct in the standard library implemented using a C struct.

Check out:

etc.

Kirby
 
R

Roy Smith

As for emulating C structs, I liked the suggestion of using a class with
only data attributes. That's a logical analogy, as in C++, it's the struct
that morphs into the basic class, with the addition of methods to data.

However, if you really want to used a low level C struct, there's actually a
struct in the standard library implemented using a C struct.

That depends on what you're trying to do. The struct module lets you
get at (or generate) packed binary data. Unless you're dealing with
binary files or network protocols, you'll probably never have a reason
to use it. In C terms, the functionality the struct module implements
is essentially a union of a struct and a char array.

The degenerate class I had suggested makes a lot more sense for the more
common case of just wanted to build an aggregate data item and be able
to refer to the members by name.
 
N

Nicola Larosa

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
So I don't buy that line of thoughts. Lists is something that can change,
and tuples is something that can't change

Amen to that, my thoughts exactly. The fact that our beloved BDFL follows the
other line of thought does not change matters, except for the unfortunate
detail that tuples do not have the "index" and "count" methods that lists
have, and that tuples definitely *should* have, too.


- --
Nicola Larosa - (e-mail address removed)

Aki: "I don't know how much time I have left."
Gary: "Who does?"
-- "Final Fantasy: The Spirits Within" movie

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFAgAfKXv0hgDImBm4RAu5yAJ4ywoypS2HfvJ3BOhrPUVYia6H8IQCfd0w/
hAviP3pdzNcOKRLrJXne26c=
=lKzF
-----END PGP SIGNATURE-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top