Multi-dimensional list initialization

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu Nov 8 05:20:24 CET 2012


On Wed, 07 Nov 2012 16:24:22 -0800, Andrew Robinson wrote:

> On 11/07/2012 01:01 PM, Ian Kelly wrote:
[...]
>> Anyway, your point was to suggest that people would not be confused by
>> having list multiplication copy lists but not other objects, because
>> passing lists into functions as parameters works in basically the same
>> way.
>
> Not quite; Although I wasn't clear;  The variable passed in is by
> *value* in contradistinction to the list which is by reference.  Python
> does NOT always default copy by reference *when it could*; that's the
> point.

It isn't clear to me whether you are describing what you think Python 
*actually* does, versus what you wish it *would* do, or what it *could* 
do in some abstract hypothetical sense.

It certainly is not true that Python passes "the variable" by value, and 
lists "by reference". Arguments are not passed to functions either by 
value or by reference.

There is a trivial test for pass-by-value semantics: does the value get 
copied? We can see that Python does not copy arguments:

py> def test(x):
...     print id(x)
... 
py> spam = []
py> print id(spam); test(spam)
3071264556
3071264556

The argument is not copied, therefore Python is not pass-by-value.

There is also an easy test for pass-by-reference semantics: can you write 
a procedure which, given two variables, swaps the contents of the 
variables? In Pascal, that is trivial.

procedure swap(var a: int, var b: int):
  var
    tmp: int;
  begin
    tmp := a;
    a := b;
    b := a;
  end;

swap(x, y);

(if I've remembered my Pascal syntax correctly).


In Python, you can swap two values like this:

a, b = b, a

but that's not sufficient. The test is to do the swap inside a function:

def swap(a, b):
    return b, a

b, a = swap(a, b)

But that fails too, since the assignment is still taking place outside 
the function.

It turns out that there is no way in Python to write such a swap 
function. Tricks such as passing the variable names as strings, then 
using exec, are hacks and don't count. Python is not pass by reference 
either.



> Hence the programmer has to remember in  foo( x,y ), the names x and y
> when assigned to -- *DONT* affect the variables from which they came.
> But any object internals do affect the objects everywhere.

Ummm.... yes?

The programmer has to remember Python's execution model in order to 
correctly predict what Python will do. What's your point?


> A single exception exists; 

There is no such exception in Python. Python always uses the same 
argument passing (parameter binding) semantics.



-- 
Steven


More information about the Python-list mailing list