tough-to-explain Python
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Wed Jul 8 02:09:19 EDT 2009
On Tue, 07 Jul 2009 20:04:46 +0000, kj wrote:
> I'm having a hard time coming up with a reasonable way to explain
> certain things to programming novices.
[...]
> Or consider this one:
>
>>>> ham = [1, 2, 3, 4]
>>>> spam = (ham,)
>>>> spam
> ([1, 2, 3, 4],)
>>>> spam[0] is ham
> True
>>>> spam[0] += [5]
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: 'tuple' object does not support item assignment
>>>> ham += [5]
>>>> spam
> ([1, 2, 3, 4, 5, 5],)
>>>>
>>>>
> What do you say to that?
That one surely is very straight forward. Just like the exception says,
tuples don't support item assignment, so spam[0] += [5] is not allowed.
But just because you have put a list inside a tuple doesn't mean the list
stops being a list -- you can still append to the list, which is what
ham += [5] does. So spam is unchanged: it is still the one-item tuple
containing a list. It is just that the list has now been modified.
This is only troublesome (in my opinion) if you imagine that tuples are
somehow magical "frozen-lists", where the contents can't be modified once
created. That's not the case -- the tuple itself can't be modified, but
the objects inside it remain ordinary objects, and the mutable ones can
be modified.
The thing to remember is that the tuple spam doesn't know anything about
the *name* ham -- it knows the object referred to by the name ham. You
can modify the name, and nothing happens to the tuple:
>>> spam
([1, 2, 3, 4, 5],)
>>> ham = [5]
>>> spam
([1, 2, 3, 4, 5],)
Or if you prefer:
>>> ham = spam[0] # label the list inside spam as 'ham'
>>> ham += [6] # modify the list labelled as 'ham'
>>> spam
([1, 2, 3, 4, 5, 6],)
>>> pork = ham # create a new label, 'pork', and bind it to the same list
>>> del ham # throw away the label 'ham'
>>> pork += [7] # modify the list labelled as 'pork'
>>> spam
([1, 2, 3, 4, 5, 6, 7],)
It's all about the objects, not the names.
--
Steven
More information about the Python-list
mailing list