The tuple and the list have a few things in common. They are both indexed containers for objects. The tuple is a very simple container to put some objects together, separated by commas, so you can send them to and from functions or stick them into lists as a group wrapped in ().
The list is a much more versatile beast, it is actually a doubly linked list, this way you can easily remove or insert objects (call them elements if you like), it is also indexed like an array. You can sort it, pop it, join it, search it, slice it and dice it, even comprehend it!
The tuple is simple and consumes little memory, the list is, by its nature, much more memory hungry. At first glance they look alike, but there is no comparison, each has their role to play.
You can call them pointers to the address of each object. You can find the address with id(tuple_element). Take a look at this ...
# globals() brings up the present dictionary of Python internals
# this would make a, b, c reference (point to) the same integer object
a = b = c = 7
tuple1 = (a, b, c)
for member in tuple1:
print member, id(member) # all point to same address as predicted
tuple2 = (7, 7, 7)
for member in tuple2:
print member, id(member) # same as tuple1, 7 is still the same object
# look how Python stores tuple1 and tuple2, surprised?
That's it. That's the big difference. Use tuples for when things shouldn't change, and lists for when they should. Tuples are thus faster (they don't have to worry about growing, shrinking, etc) while lists are more flexible.
Secondly, a list is NOT implemented as a linked list. A list is a growable array, like an C++'s std::vector . They're called lists because they are lists of items, in the non-computer-science way. (Not to mention list doesn't imply linked list, it's just more common to see linked list than any other useage of list)
Thirdly, *everything* in Python is stored as a reference (or pointer, if that's the term you prefer). Everything is also an object. Integers and Integers, like tuples, are immutable. The function id returns "the identity of an object. This is guaranteed to be unique among simultaneously existing objects." It is true that under the normal python interpreter this is a pointer to the object. So each instance of an object would have its own unique id, then why did all of the 7s have the same id? This is because python stores the first 100 integers internally, and anytime they are created it will just reference the existing immortal version. This is one of a few optimizations Python makes that will make the id function return less than helpful results. The other is that most constants (strings or integers) will end up being the same instance (since you can't *ever* change them, they can be shared as much as possible with no harmful side effects)
So to make a long story short, keep lists around when you want to add or remove items, or modify item order. Keep tuples around when they're not going to change (or at least not often).
Thanks for clearing a few things up! We are all learning. I got to look in the Python source code what list really is patterned after. I am suspecting similarity to the C++ STL list rather than vector.
A cursory look at the source code shows the Python list to be much less advanced than the C++ STL list container. I am a little disappointed!
The string methods like lower(), isdigit(), etc. all assume that the sequence consists of single characters. I think of a tuple as a string where each 'character' could be literally any object whatsoever. What would it mean to have a function like the following?
tup = (3,"hi", "4")
tup2 = tup.isalphanum()
Even reverse() could be ambiguous with tuples: Which is the correct output?