Lists are mutable sequences with many and many methods (both mutating and non-mutating) that are most often used as general-purpose containers (their elements can be objects of any type in general, although sometimes it is considered a better style for lists to have elements of the same type or types to be used equivalently).
Tuples are immutable sequences with a very small number of methods (all non mutating special ones) that are most often used when you need immutability to use a container as an element in a set or as a key in a dict (although elements must also be immutable - for example, strings, numbers or other nested tuples to make this work). Their objects can be objects of any type, and it is perfectly normal if tuples have elements of different and different types.
There are several cases where either a tuple or a list will work just as well, and in such few cases the fact that tuples are slightly smaller and faster for assembly can be used to control the decision in favor of tuples, For example, when a function should return several results most normally use
return fee, fie, foo, fum
ie, return a four-point tuple, not
return [fee, fie, foo, fum]
those. to return a list with four elements - in addition (small profit), the common idiom βreturn a tupleβ also addresses the problem in which often multiple results are not the same and interchangeable types, so, stylistically speaking, you can use the list in any case considered more doubtful.
A useful option for tuple is its subtype collections.namedtuple (requires Python 2.6 or later), which allows you to access elements by name (with attribute syntax) and also by index (in the usual way). For example, with import collections at the top of the module, the above return may become ...
freturn = collections.namedtuple('freturn', 'fee fie foo fum') def f(): ... return freturn(fee, fie, foo, fum)
Now the caller f() can use the return value as a tuple, as before, but would get nice alternatives like ...:
r = f() print r.fie
instead of less clear and readable
print r[1]
It is important to note that a subclass called tuple created using collections.namedtuple essentially does not contain additional overhead compared to using a tuple directly or, as its docs believe,
they are lightweight and do not require more memory than regular tuples.