classification
Title: Tutorial: Add a bit on the difference between tuples and lists
Type: enhancement Stage: resolved
Components: Documentation Versions: Python 3.2, Python 3.3, Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: ezio.melotti Nosy List: docs@python, eric.araujo, ezio.melotti, python-dev, r.david.murray, terry.reedy, zach.ware
Priority: normal Keywords: patch

Created on 2012-05-17 16:56 by zach.ware, last changed 2012-06-17 15:23 by eric.araujo. This issue is now closed.

Files
File name Uploaded Description Edit
tuple vs list.patch zach.ware, 2012-05-17 16:56 Patch to add tuple vs. list differences to tutorial review
tuple vs list.patch.2 zach.ware, 2012-05-18 21:59 Take 2 review
issue14840.diff ezio.melotti, 2012-05-19 21:59 Patch against 2.7.
Messages (14)
msg160982 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2012-05-17 16:56
I was looking through the documentation source files for things I might be able to fix, and stumbled across "XXX Add a bit on the difference between tuples and lists." in Doc\tutorial\datastructures.rst. So I took a stab at adding some prose to address that comment, reproduced here:

"""
Though tuples may seem very similar to lists, their immutability makes them
ideal for fundamentally different usage.  In typical usage, tuples are a
heterogenous structure, whereas lists are a homogenous sequence.  This tends to
mean that, in general, tuples are used as a cohesive unit while lists are used
one member at a time.
"""

Have I missed anything important (like the whole point) or is there anything I could phrase better?

Should this be applied to the tutorials of previous versions?
msg160985 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-05-17 17:13
I personally like your suggested text, but there have been some discussion on the topic (on python-ideas iirc) and some people think that it's ok to use tuples like immutable lists, rather than just structures with heterogeneous elements similar to C's structs.
msg160986 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-05-17 17:18
I don't think that the suggested text contradicts that.  (Especially the wording "tends to".)  So I think this might be a reasonable addition, but I can see that "some people" might get upset :)
msg160987 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2012-05-17 17:20
Perhaps an added line at the end, something like 'Of course, should you need an immutable list, tuples are quite handy for that, too.'?
msg160999 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-05-17 18:43
Link to the discussion: https://groups.google.com/d/msg/python-ideas/P3lEYU9u0DU/H0gcuAAJvEgJ

The actual discussion about tuples starts on https://groups.google.com/d/msg/python-ideas/P3lEYU9u0DU/JW2Lq3KYA4QJ and continues with the following posts.
msg161022 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012-05-17 22:16
Zachary, you are brave/foolhardy to take this on;)

I agree that the XXX comment should be removed. One possible resolution is to do just that, replacing it with nothing.

I would note that the fuss over tuples versus lists comes from a time before iterators became a common way to pass around and process sequences. This, in a sense, makes tuples and lists more similar that they were before in that iterators have mostly replaced one of the list uses that made lists different from tuples. We do not fuss over whether an iterator is 'homogeneous' or 'heterogeneous'. Each is, of course, mutable until exhausted.

Another change is that now isinstance(x, object) is True for everything, so that one can now view all concrete collections as homogeneous at the Python level as well as at the C implementation level. Things were different before the unification of types and classes, completed in 3.0.

As to the proposal: I am one of the 'some people'. 'Tends to' helps a lot. Now to be picky.

I would say that tuples and list are similar to each other in being concrete sequences of objects (instances of class <object>). I would remove 'fundamentally'.

The rest of the initial paragraph leaves out the usage of tuples as constant sequences (which is to say, immutable 'all the way down'). First is the hard-coded constant: consider

>>> def f(): return (((1,2),(3,4)),((5,6),(7,8)))

>>> dis(f)
  1           0 LOAD_CONST    15 ((((1, 2), (3, 4)), ((5, 6), (7, 8)))) 
              3 RETURN_VALUE  

versus
       
>>> def fl(): return[[[1,2],[3,4]],[[5,6],[7,8]]]
      
>>> dis(fl)
  1           0 LOAD_CONST               1 (1) 
              3 LOAD_CONST               2 (2) 
              6 BUILD_LIST               2 
              9 LOAD_CONST               3 (3) 
             12 LOAD_CONST               4 (4) 
             15 BUILD_LIST               2 
             18 BUILD_LIST               2 
             21 LOAD_CONST               5 (5) 
             24 LOAD_CONST               6 (6) 
             27 BUILD_LIST               2 
             30 LOAD_CONST               7 (7) 
             33 LOAD_CONST               8 (8) 
             36 BUILD_LIST               2 
             39 BUILD_LIST               2 
             42 BUILD_LIST               2 
             45 RETURN_VALUE         

Second are sequences used as keys, regardless of 'geneity.

Third are the homogeneous sequences that the language syntax requires to be tuples, not lists: except, issubclass, isinstance. There are also the typically homogeneous tuples for *args  and possibly homogeneous second argument to % interpolation. In other words, the language itself does not support the second sentence.

On the other hand, if one has a heterogeneous list, perhaps from a list comprehension, that will not be hashed, there may be no need other than philosophical purity to convert it to a tuple. Im/mutability is part of the definition and operaton of the language. Homo/heter/geneity is not (that I can think of at the moment).

I do not especially like the suggested add on sentence as is. 'Immutable list' is wrong; a tuple is an immutable sequence, and what one typically needs is a constant (hashable) sequence, and if one does, a tuple is essential, not just 'handy'.
msg161085 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2012-05-18 21:59
I'll go with foolhardy, or just "green" :P. I wasn't aware that this topic was quite as contentious as it seems to be.

I agree that tuples and lists are similar.  I was trying to keep my wording at "here's another way to look at things that you may not have thought of before" without discrediting other ways of thinking, but looking at it again today, there is definite room for improvement on that front.  As for "fundamentally different," my intent was to condense "tuples can be used in a way that lists don't fit as well in, and that usage is much different than lists' usual usage" into as few words as I could; referring to the usages rather than the objects being fundamentally different.

I'm guessing your main issue with the second sentence is "typical usage."  I agree, that really isn't the best choice of words, especially when trying to stay away from "this is how to do it, don't deviate."

I didn't leave out other tuples uses intentionally, but my purpose was really to point out another way of thinking.  Not long ago, I was wondering what the difference between tuples and lists really was and went searching.  When I found something about "heterogenous structure vs. homogenous sequence," it was like a light bulb turning on in my head.  I hadn't seen anything like that anywhere in the tutorial or docs before, and it made a lot of things make more sense.  Your dis() examples have done the same kind of thing for me, to a lesser extent; I'd never realized just how much less work it is for the interpreter to create a tuple than a list.  It's my belief that the tutorial should pack as many "ah ha!" moments as it can into as little space as it can.

So, here's another stab:

"""
It may seem that tuples are very similar to lists (and they are in many ways),
but their immutability makes them ideal for some cases that lists don't fit
quite as well.  Though hetero- or homogeneity is in no way a programmed property
of anything in Python's syntax or the standard library, it can be helpful to
think of tuples as heterogenous structures, and lists as homogenous sequences.
When used in this way, tuples are used as a coherent unit while lists are used
one member at a time.  This is not to say tuples can only be used as a
heterogenous structure.  In fact, there are parts of Python's own syntax that
require a tuple that happens to be a homogenous sequence, such as the
:keyword:`except` clause of a ``try ... except`` statement, :func:`issubclass`,
and :func:`isinstance`.
"""
msg161124 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-05-19 14:48
I think I liked the first version more, possibly with a few minor changes:

> Though tuples may seem very similar to lists, their immutability
> makes them ideal for fundamentally different usage.

I would drop the 'very', and I'm not sure that it's the immutability that enables this "fundamentally different" uses.

> In typical usage, tuples are a heterogenous structure, 
> whereas lists are a homogenous sequence.

Instead of "In typical usage" this could just be "Usually".

> This tends to mean that, in general, tuples are used
> as a cohesive unit while lists are used one member at a time.

This could even be dropped IMHO, or something could be said about index access (or attribute access in case of namedtuples) vs iteration.

Maybe something like this could work:
"""
Though tuples may seem similar to lists, they are often used in different situations and for different purposes.
Tuples are immutable, and usually contain an heterogeneous sequence of elements that are accessed via tuple-unpacking or indexing (or by attribute in the case of namedtuples).  [Sometimes tuples are also used as immutable lists.]
Lists are mutable, and their elements are usually homogeneous and are accessed by iterating on the list.
"""

FWIW homogeneous tuples are ok too, but here "homogeneous" is just a special case of "heterogeneous".  IMHO the main difference between lists and tuples is the way you access the elements (and homogeneous vs heterogeneous is just a side-effect of this); the fact that they are mutable or not is a secondary difference.
msg161141 - (view) Author: Terry J. Reedy (terry.reedy) * (Python committer) Date: 2012-05-19 17:38
I am ok with Ezio's 3rd version.
msg161167 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-05-19 21:59
Here's a patch against 2.7.
I changed a bit the previous paragraphs to make this fit better.
msg161286 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2012-05-21 18:28
Ezio's version looks pretty good to me.  About the only quibble I can think of is the removal of the example uses; they still apply and do help the point. Just tacking on "Classic examples of tuples include (x, y) coordinate pairs and database records." to the end of the paragraph would take care of that.

Also a point of grammar; do we iterate *on* a list, or do we iterate *over* a list?  I'm pretty sure I've seen both; 'on' does make sense to me but 'over' is the word my brain always seems to choose.
msg163059 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2012-06-17 12:13
New changeset bb63919cde6e by Ezio Melotti in branch '2.7':
#14840: Add a bit on the difference between tuples and lists.  Initial patch by Zachary Ware.
http://hg.python.org/cpython/rev/bb63919cde6e

New changeset 3550416d83b3 by Ezio Melotti in branch '3.2':
#14840: Add a bit on the difference between tuples and lists.  Initial patch by Zachary Ware.
http://hg.python.org/cpython/rev/3550416d83b3

New changeset 2fad115408e9 by Ezio Melotti in branch 'default':
#14840: merge with 3.2.
http://hg.python.org/cpython/rev/2fad115408e9
msg163060 - (view) Author: Ezio Melotti (ezio.melotti) * (Python committer) Date: 2012-06-17 12:15
Fixed, thanks for the patch!
msg163070 - (view) Author: √Čric Araujo (eric.araujo) * (Python committer) Date: 2012-06-17 15:23
Great addition, thanks!
History
Date User Action Args
2012-06-17 15:23:00eric.araujosetmessages: + msg163070
2012-06-17 12:15:46ezio.melottisetstatus: open -> closed
resolution: fixed
messages: + msg163060

stage: patch review -> resolved
2012-06-17 12:13:55python-devsetnosy: + python-dev
messages: + msg163059
2012-05-21 18:28:54zach.waresetmessages: + msg161286
2012-05-19 21:59:19ezio.melottisetfiles: + issue14840.diff
assignee: docs@python -> ezio.melotti
messages: + msg161167
2012-05-19 17:38:51terry.reedysetmessages: + msg161141
2012-05-19 14:48:54ezio.melottisetmessages: + msg161124
2012-05-18 21:59:29zach.waresetfiles: + tuple vs list.patch.2

messages: + msg161085
2012-05-17 22:16:26terry.reedysetmessages: + msg161022
2012-05-17 18:43:24ezio.melottisetnosy: + terry.reedy, eric.araujo
messages: + msg160999
2012-05-17 17:20:58zach.waresetmessages: + msg160987
2012-05-17 17:18:23r.david.murraysetnosy: + r.david.murray
messages: + msg160986
2012-05-17 17:13:39ezio.melottisetversions: + Python 2.7, Python 3.2
nosy: + ezio.melotti

messages: + msg160985

stage: patch review
2012-05-17 16:56:09zach.warecreate