Tuple question

W

Will McGugan

Hi,

Why is that a tuple doesnt have the methods 'count' and 'index'? It
seems they could be present on a immutable object.

I realise its easy enough to convert the tuple to a list and do this,
I'm just curious why it is neccesary..


Thanks,

Will McGugan
 
W

Will McGugan

Wai said:
I'm not sure what do you mean by index. But you can use len() to get
the number of objects in a tuple. e.g.

3

Lista have an index method that returns the index of the first occurance
of an element, but tuple doesnt (nor count). Just wondering why.
>>> l= [ 1, 2, 3 ]
>>> t= ( 1, 2, 3 )
>>> l.index(2) 1
>>> t.index(2)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in ?
t.index(2)
AttributeError: 'tuple' object has no attribute 'index'
 
W

Wai Yip Tung

Oops I misunderstood that you said about count and index. Now I got it.

Speaking as a user of Python, here is my take:

You consider tuple an immutable version of list. But in Python's design
they have different purpose. List a collection of homogeneous items, while
tuple is a convenient grouping of any kind of items. For example, you can
use them this way:

users = ['admin', 'user1', 'user2']
address = ('www.python.org', 80)

index and count only make sense when the collection is homogeneous.
Therefore they are not defined for tuple.

tung

Wai said:
I'm not sure what do you mean by index. But you can use len() to get
the number of objects in a tuple. e.g.
t=(1,2,3)
len(t) 3

t[2]
3

Lista have an index method that returns the index of the first occurance
of an element, but tuple doesnt (nor count). Just wondering why.
l= [ 1, 2, 3 ]
t= ( 1, 2, 3 )
l.index(2) 1
t.index(2)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in ?
t.index(2)
AttributeError: 'tuple' object has no attribute 'index'
 
G

Gandalf

users = ['admin', 'user1', 'user2']
address = ('www.python.org', 80)

index and count only make sense when the collection is homogeneous.
Therefore they are not defined for tuple.

Why?

address = ['www.python.org',80]

A list can hold any kind of objects. I think that the 'index' method for
tuples would be a good idea.
 
R

Roy Smith

users = ['admin', 'user1', 'user2']
address = ('www.python.org', 80)

index and count only make sense when the collection is homogeneous.
Therefore they are not defined for tuple.

Why?

address = ['www.python.org',80]

A list can hold any kind of objects. I think that the 'index' method for
tuples would be a good idea.[/QUOTE]

Personally, I think it should be more general. I think index should be
a sequence method, and tuple should just inherit from that.
 
D

Donn Cave

users = ['admin', 'user1', 'user2']
address = ('www.python.org', 80)

index and count only make sense when the collection is homogeneous.
Therefore they are not defined for tuple.

Why?

address = ['www.python.org',80]

A list can hold any kind of objects. I think that the 'index' method for
tuples would be a good idea.[/QUOTE]

Yes, lists and tuples can hold the same kinds of objects.
I don't care whether I manage to convince you that the
index method is not needed, but here's my take on an aspect
of the the homogeneity issue, a somewhat obscure point that
isn't explained in the FAQ.
(
http://www.python.org/doc/faq/general.html#why-are-there-separate-tuple-a
nd-list-data-types )

Lists are not naturally homogeneous because each item is
of the same type as the next. That would be sort of absurd
in a language like Python, where that kind of typing isn't
done. Rather they are homogeneous because if you say that
that an object is "list of (something)", typically a slice
of that list will still be a valid "list of (something)" -
a list of hosts, a list of dictionary keys, etc. In this
less concrete sense of type, the list itself has a type
that applies not only to the whole list but to any slice.
The list object has all kinds of support for iterative
traversal, deletion, extension, etc., because these are
naturally useful for this kind of sequence.

On the other hand, we normally use tuples for data that
is meaningful only when it's intact. The (key, value)
pair that comes back from dict.items(), for example. Each
value may very well be a string, but the sequence is not
homogeneous in the sense we're talking about, and index()
is not useful.

Donn Cave, (e-mail address removed)
 
C

Colin J. Williams

Wai said:
Oops I misunderstood that you said about count and index. Now I got it.

Speaking as a user of Python, here is my take:

You consider tuple an immutable version of list. But in Python's design
they have different purpose. List a collection of homogeneous items,
while tuple is a convenient grouping of any kind of items. For
example, you can use them this way:

users = ['admin', 'user1', 'user2']
address = ('www.python.org', 80)

index and count only make sense when the collection is homogeneous.
What about:

addresses= list(address)
print addresses
users.append(address)
print users

Colin W.
Therefore they are not defined for tuple.

tung

Wai said:
I'm not sure what do you mean by index. But you can use len() to get
the number of objects in a tuple. e.g.

t=(1,2,3)
len(t)

3

t[2]

3

Lista have an index method that returns the index of the first
occurance of an element, but tuple doesnt (nor count). Just wondering
why.
l= [ 1, 2, 3 ]
t= ( 1, 2, 3 )
l.index(2) 1
t.index(2)
Traceback (most recent call last):
File "<pyshell#8>", line 1, in ?
t.index(2)
AttributeError: 'tuple' object has no attribute 'index'
 
G

Gandalf



This is from that thread:
Note that while .index() makes sense for some sequences,
such as strings and lists, it doesn't make sense for the
way in which tuples are "supposed to be used", which is
as collections of heterogeneous data and not usually as
simply read-only lists.

Why it is not useful to have an index() method for collections of heterogeneous data?

Suppose, you have big amount of data stored in tuples (for using less memory).
You may want to extract slices from the tuploes from a given index determined by an object.
This is just an example, however it is quite realistic (e.g. using tuples instead of lists
because there is a huge amount of static data that you need to access quickly).
 
P

Peter Hansen

Gandalf said:
This is from that thread:

Why it is not useful to have an index() method for collections of
heterogeneous data?

Because you will already know where the different items or
types of items are in the sequence. If you don't, it's
probably not heterogeneous data using the definition that
is being used by those saying that tuples are not just
immutable lists.
Suppose, you have big amount of data stored in tuples (for using less
memory).

Why do you think tuples use significantly less memory than lists?
As far as I know, they don't. (They do use less, but if you are
really talking about huge amounts of data such that you would
be trying to optimize in this way, then the amount that they use
is not *significantly* less.)
You may want to extract slices from the tuploes from a given index
determined by an object.
This is just an example, however it is quite realistic (e.g. using
tuples instead of lists
because there is a huge amount of static data that you need to access
quickly).

Actually, it's realistic but unwise and a waste of time. Use lists,
that's what they were meant for...

-Peter
 
R

Roy Smith

Please see these recent threads, and read the FAQ:

http://groups.google.ca/groups?threadm=mailman.2685.1093979591.5135.python-l
ist%40python.org


This is from that thread:
Note that while .index() makes sense for some sequences,
such as strings and lists, it doesn't make sense for the
way in which tuples are "supposed to be used", which is
as collections of heterogeneous data and not usually as
simply read-only lists.

Why it is not useful to have an index() method for collections of
heterogeneous data?

Suppose, you have big amount of data stored in tuples (for using less
memory).
You may want to extract slices from the tuploes from a given index determined
by an object.
This is just an example, however it is quite realistic (e.g. using tuples
instead of lists
because there is a huge amount of static data that you need to access
quickly).[/QUOTE]

Also, you must use tuples instead of lists as dictionary keys. If your
keys are inherently arbitrary length ordered collections of homogeneous
data, you might very well want to use things like index() on the keys.
In this case, they really are "immutable lists".

I understand the argument that tuples are supposed to be the moral
equivalent of anonymous C structs, but if that's the case, why do things
like len() and slicing work on them? Not to mention "in" (either as a
test or as an iterator). None of those things make sense to do on
structs.

It's really pretty arbitrary that of the things you can do on immutable
sequences, index() and count() are special-cased as innapropriate
operations for tuples.

Looking over the Zen list, I'd say any of:

Simple is better than complex.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.

argue for allowing index() and count() to be used on tuples.
 
A

Aahz

Why do you think tuples use significantly less memory than lists?
As far as I know, they don't. (They do use less, but if you are
really talking about huge amounts of data such that you would
be trying to optimize in this way, then the amount that they use
is not *significantly* less.)

Actually, if you have large numbers of short sequences, the memory
savings from tuples can indeed be significant. I don't remember off-hand
what the number is, but I think it's something on the order of 20%.
--
Aahz ([email protected]) <*> http://www.pythoncraft.com/

"To me vi is Zen. To use vi is to practice zen. Every command is a
koan. Profound to the user, unintelligible to the uninitiated. You
discover truth everytime you use it." (e-mail address removed)
 
M

Mel Wilson

Why it is not useful to have an index() method for collections of heterogeneous data?

Since the data are heterogenous, they're interpreted
according to their positions in the tuple. In a tuple of
name, address, city:

('Marlene Stewart Street', 'Lois Lane', 'Margaret Bay')

It makes no sense to exchange elements, or treat one like
another, no matter that they're all strings, and no matter
what you think they look like. Just finding the value 'Lois
Lane' in the tuple doesn't tell you what 'Lois Lane' means.

All of which is belied by our recent experience of rows
of database fields kicked off by a row of column labels:

('name', 'address', 'city')
('Marlene Stewart Street', 'Lois Lane', 'Margaret Bay')
('Cecil Rhodes', 'Frank Court', 'Saint John')

Then my first and only reaction is to turn the whole mess into a
list of dictionaries and forget about the list/tuple distinction
for the rest of the day.

Regards. Mel.
 
D

Dan Christensen

I'm not sure I buy the arguments against an index operation for
tuples. For example, suppose we were conducting a vote about
something, hmm, let's say decorator syntax. <wink> And suppose that
each person is allowed three distinct votes, ranked in order, with the
first vote getting 3 points, the second 2, and the third 1. We might
store the votes in a database, whose rows would naturally be tuples
like

('J2', 'C64', 'X11')

Now suppose we want to calculate the total number of points for
proposal X, but don't need to compute the totals for the other
choices. Code like the following would be a pretty natural
approach:

for row in rows:
try:
points += 3-row.index(X)
except:
pass

I realize that there are different ways to code it, but most
are simply reimplementations of the proposed index function.

Dan
 
J

Jason Lai

Dan said:
I'm not sure I buy the arguments against an index operation for
tuples. For example, suppose we were conducting a vote about
something, hmm, let's say decorator syntax. <wink> And suppose that
each person is allowed three distinct votes, ranked in order, with the
first vote getting 3 points, the second 2, and the third 1. We might
store the votes in a database, whose rows would naturally be tuples
like

('J2', 'C64', 'X11')

Now suppose we want to calculate the total number of points for
proposal X, but don't need to compute the totals for the other
choices. Code like the following would be a pretty natural
approach:

for row in rows:
try:
points += 3-row.index(X)
except:
pass

I realize that there are different ways to code it, but most
are simply reimplementations of the proposed index function.

Dan

Well,

for index, row in enumerate(rows):
points += 3 - i

It's not really reimplementing the index function. You already have the
index. I think for most of the cases where people use tuples, you
already know what you're using each index for.

- Jason
 
D

Dan Christensen

Jason Lai said:
for index, row in enumerate(rows):
points += 3 - index

[I changed "i" to "index" in the last line.]

That doesn't do the same thing, but that's because my description
wasn't clear. rows is a list of tuples, with each tuple being one
person's three votes. E.g.

rows = [('J2', 'C64', 'X11'), ('U2', 'J2', 'P3000')]

So if X == 'J2', the code should calculate 3+2=5 points.

Dan
 
P

Peter Hansen

Aahz said:
Actually, if you have large numbers of short sequences, the memory
savings from tuples can indeed be significant. I don't remember off-hand
what the number is, but I think it's something on the order of 20%.

Differing definitions of "significant", I guess, because
nothing less than about a 2:1 ratio would make me consider
optimizing to use tuples instead of lists...

Consider, for example, that one actually has to build the
tuple in the first place... how can you do that without
having the info in a list to begin with? (I'm sure there
are ways if one is ingenious, but I think the answers
would just go to prove the point I was making.)

-Peter
 
J

Jason Lai

Dan said:
Dan Christensen wrote:



for index, row in enumerate(rows):
points += 3 - index


[I changed "i" to "index" in the last line.]

That doesn't do the same thing, but that's because my description
wasn't clear. rows is a list of tuples, with each tuple being one
person's three votes. E.g.

rows = [('J2', 'C64', 'X11'), ('U2', 'J2', 'P3000')]

So if X == 'J2', the code should calculate 3+2=5 points.

Dan

Ah, okay, I see my mistake. I should read closer before replying :p

Well, I see your point, although I still don't think it would happen
that often. I also don't see it as a newbie trap, because currently all
the other "mutable sequence" member functions are only for lists, not
tuples. Index and count are the only mutable sequence functions that
might apply to tuples. One could argue that those functions might be
useful (to a lesser extent, probably) for iterators too.

- Jason Lai
 
D

Donn Cave

Quoth Dan Christensen <[email protected]>:
| I'm not sure I buy the arguments against an index operation for
| tuples. For example, suppose we were conducting a vote about
| something, hmm, let's say decorator syntax. <wink> And suppose that
| each person is allowed three distinct votes, ranked in order, with the
| first vote getting 3 points, the second 2, and the third 1. We might
| store the votes in a database, whose rows would naturally be tuples
| like
|
| ('J2', 'C64', 'X11')
|
| Now suppose we want to calculate the total number of points for
| proposal X, but don't need to compute the totals for the other
| choices. Code like the following would be a pretty natural
| approach:
|
| for row in rows:
| try:
| points += 3-row.index(X)
| except:
| pass
|
| I realize that there are different ways to code it, but most
| are simply reimplementations of the proposed index function.

The algorithm is fine, it's the choice of sequence that's debatable.
Once you get index() for this application, next you'll want append().
After all, there's no apparent reason that at any time there must be
exactly 3 votes, so what if you want to collect data in several passes -

for person, vote in data:
try:
row = votes[person]
except KeyError:
row = []
votes[person] = row
if len(row) < 3:
row.append(vote)

Your application is really suited for a list or dictionary. It can,
conceptually, support mutations like insert, delete and append, with
fairly obvious semantics in terms of your application. I mean, if
you delete the first item, then the second item becomes the 3 point
vote, etc. (In an application where that's not the case, then you
probably want a dictionary, where deleting whatever item has no
effect on the others.) Compare with the mtime tuple returned by
time.localtime() - minus the first item, about the most you can say
is it's an mtime minus its first item.

No one is saying you must use a list then. Do whatever you want!
But no one is forcing you to use a tuple, either (in this hypothetical
application), and if you need an index function, you know where to get it.

Donn Cave, (e-mail address removed)
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top