Python newbie

Steven D'Aprano steven at
Fri Sep 19 10:13:05 CEST 2008

On Fri, 19 Sep 2008 09:13:48 +0200, Mladen Gogala wrote:

> I am a Python newbie who decided to see what that Python fuss is all
> about. Quite frankly, I am a bit perplexed. 

Naturally you will be perplexed if you assume that Python is just Perl 
with a more verbose syntax. It isn't.

> After having had few months
> of experience with Perl (started in 1994 with Perl v4, and doing it ever
> since) , here is what perplexes me:
> perl -e '@a=(1,2,3); map { $_*=2 } @a; map { print "$_\n"; } @a;'
> The equivalent in Python looks like this:

Actually, no it doesn't. The equivalent looks more like this:

$ python -c 'a=[1,2,3]; a=[2*x for x in a];
for x in a:
    print x'

Now, to go on with your questions:

> 1) Why is the array "a" unchanged after undergoing a transformation with
>    map?

Because it hasn't undergone a transformation at all. The list (not array) 
a remains unchanged, because map returns a new list.

> 2) Why is it illegal to pass a built-in function "print" to map?

Because print is not a function, it is a statement. However, in Python 3, 
that design wart has been corrected.

> 3) Why is the array "a" unchanged after undergoing an explicit
>    transformation with the "for" loop?

Because the list a hasn't undergone any such transformation. Rebinding a 
name is not an explicit transformation to the object that used to be 
bound to the name. And if that sentence is gobbledygook to you, that 
demonstrates that Python is not Perl and you shouldn't assume a one-to-
one semantic relationship between syntactical elements.

> 4) Is there an equivalent to \$a (Perl "reference") which would allow me
> to decide when a variable is used by value and when by reference?

Python is neither call-by-reference nor call-by-value, although you will 
have many people swear black and blue that it is one or the other. With 
respect to all of them, they are wrong. Python's calling model is "call 
by object". See here for more detail:

If you insist on a false dichotomy between call-by-reference and call-by-
value, then you won't often go wrong if you think of Python:

- being almost always call-by-reference, except for some odd corner cases 
which look almost, but not quite, like call-by-value;

- being almost always call-by-value, but only if you think of the values 
as pointers.

> How can I make sure that
> for x in a: x=2*x
> actually changes the elements of the array "a"?

By explicitly changing the elements of the list. Here's one very old-
fashioned way of doing so:

>>> a = [1,2,3]
>>> for i in range(len(a)):
...     a[i] = a[i]*2
>>> a
[2, 4, 6]

Here's a more Pythonic alternative:

>>> a = [1,2,3]
>>> a = [2*x for x in a]


More information about the Python-list mailing list