3

I am learning Python and more specifically I am exploring the scoping rules.

I tried the following "experiment":

def increment(n): 
   n += 1 
   print(n)
   return n

n = 1 
increment(n) 
print(n) 

This piece of code outputs: 2 , 1. Should n't it output instead 2, 2 since the variable n is returned to the global environment?

Your advice will be appreciated.

4

2 Answers 2

5

You have two distinct variables (names) here: one lives in the global scope, the other is local to increment. Rebinding the local one in increment doesn't impact the global one, and the fact that increment returns it's own n has no impact on the global one either (the fact they have the same name is irrelevant). If you want to have the global n pointing to the value returned by increment(), you have to rebind it explicitely:

n = 1
print(n)
n = increment(n)
print(n)
Sign up to request clarification or add additional context in comments.

Comments

-2

Consider the following modification of the snippet above:

def increment(n): 
   n[0] += 1 
   print(n[0])
   return n

n = [1] 
increment(n) 
print(n[0]) 

This prints 2, 2.

In many computer languages (among them Javascript) a difference is made between function parameters that are primitive (like the integers 1 and 2) or compound (like the one-element list n[0]). Usually primitives are passed by value (their values are copied to temporary variables internal to the function). Compound entities are usually not copied, but passed by reference (the address of the entity is passed and the entity is accessed from within the function). If I look at the output of the two code snippets above, it seems to me that Python makes that difference too.

PS After I wrote this I looked at a 2009 Stack Overflow question. A primitive entity is called in the most popular 2009 answer an immutable object and a compound entity is called a mutable object, otherwise my answer is in agreement with the older answer.

4 Comments

Python doesn't have primitive types, everything's an object, and mutability doesn't map well (a tuple is an immutable compound entity, for example). Also all arguments are passed by object reference, neither value nor reference: stackoverflow.com/a/33066581/3001761
Being new to Python I would like to know how one can rationalize the difference in calling the function increment() with the scalar n or the with the list [n]. The difference is undeniable, either 2,1 or 2,2 is printed. Jonrsharpe, do you know how to explain this?
You're literally doing different things. In one you're mutating a mutable data structure: n[0] = n[0] + 1 (note that it's unconventional to return something when you mutate the argument). In the other you're reassigning the name from one immutable object to another, new immutable object: n = n + 1.
-1 As already observed, this answer isn't correct. The analog to the original post would be reassigning n to a new list, n = [2] within increment (in place of n[0] += 1). This will also output 2, 1, consistent with the original post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.