Reputation: 309
As a new python programmer, I have two questions about list and really appreciate your advice:
Question 1:
For the following code:
nums1 = [1,2,3,8,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
def merge(nums1, m, nums2, n):
nums1[:] = sorted(nums1[:m]+nums2)
merge(nums1, m, nums2, n)
nums1
What it does is: pass list nums1 and list nums2 into merge function, and merge them into list nums1 with the first m items in nums1 and n items in nums2, and sort list nums1. So the results are: [1, 2, 2, 3, 5, 6] So my question is: since list nums1 was defined outside the scope of function merge, how come it has the ability to update nums1? And in the following example:
x = 10
def reassign(x):
x = 2
reassign(x)
x
Variable x was defined outside of function reassign, and the reassign function was not able to update x defined outside of reassign, which is why x returns 10.
Question 2:
In the above code I provided, if I write it like the following:
Note: I just modified nums1[:] into nums1 when assigning sorted(nums1[:m]+nums2)
nums1 = [1,2,3,8,0,0,0]
m = 3
nums2 = [2,5,6]
n = 3
def merge(nums1, m, nums2, n):
nums1 = sorted(nums1[:m]+nums2)
merge(nums1, m, nums2, n)
nums1
nums1 returns [1,2,3,8,0,0,0], so my question is: after adding [:] after nums1, how come the function has the ability to nums1? What does [:] in that example?
Upvotes: 2
Views: 413
Reputation: 8025
To replicate what you are saying, take the following:
var = 10
lst = [1, 2, 3]
def func():
var = 11
lst[:] = [1, 2, 3, 4]
func()
print(var, lst)
The above will output 10 [1, 2, 3, 4]
. Now notice the following:
var = 10
lst = [1, 2, 3]
def func():
print(var)
print(lst)
func()
Outputs 10 [1, 2, 3]
-- so we know that functions can access global variables, but in most cases cannot modify them. Now let us look at both cases (int
and list
): The two cases are followed:
var
variable is not being modified due to the difference of reference between local and global scope (while we can access the global scope, we can't modify it). I recommend playing around with printing globals()
and locals()
for fun. This case can be fixed if we do: def func():
global var
var = 11
lst
variable is being modified with the [:]
notation because as referenced here, the slice assignment [:]
utilizes the operator
function setitem()
. Therefore, technically, lst[:] =
is the equivalent of doing:from operator import setitem
lst = [1, 2, 3]
# Both of these are equivalent.
lst[:] = [1, 2, 3, 4]
setitem(a, slice(0, len(a)), [1, 2, 3, 4])
setitem
does not discriminate between local or global scopes.
Upvotes: 1
Reputation: 77
If you are confused, take the following.
Firstly placement and change are not the same things
nums1 = [1,2,3,8,0,0,0]
lst = None
m = 3
nums2 = [2,5,6]
n = 3
def merge(nums1, m, nums2, n):
global lst
lst = sorted(nums1[:m]+nums2)
merge(nums1, m, nums2, n)
print(lst)
nums1[:]
means your whole list.
If you use nums1[:]
instead of nums1
You can change your former nums1[:]
list using sorted(nums1[:m]+nums2)
. When you do this change what both your former and latest list, so you in the nums1
array list changing new with new attached variables place each other. But if you use only nums1
instead of nums1[:]
the latest nums1
now refers to a different list from the former.
Upvotes: 0
Reputation: 2048
(Don't use the [:]
thing. That's horrible.)
When you say nums1[:]
Python is finding the GLOBAL list called nums1
.
However, inside of a function, Python pays attention to new variables first. Why?
- it would suck if any variable name you ised outisde of a function, was now restricted from being used as DIFFERENT variable inside the function
H = True # some variable.pretend it means "High"
def euro_height(inches):
H = inches # since H is a nice abbrev for height in inches
return H*2.54 # Centimeters
I don't want my H
inside the function to overwrite something I already stored. Therefore, within euro_height
, H
is considered a different local variable, which only that function can see and use. If I want to use the H
from outside of the function, I'd have to first tell Python to access it. Then I can use it.
H = True # some variable.pretend it means "High"
def euro_height(inches):
global H
print(H) # will say true
renamed_var = inches # since H is a nice abbrev for height in inches
return renamed_var*2.54 # Centimeters
If I were to assign H = inches
inside the function now, it would overwrite the True
value for the global H
. So instead, I rename it, because there is already an H
I want to use.
The name for all this is called namespaces. Hopefully, you are doing a Python tutorial. You will understand this when they teach functions. I highyl suggest doing a tutorial if you aren't.
For more about this answer related to what happened to you, look at the interactive examples here https://www.programiz.com/python-programming/global-local-nonlocal-variables
Also, never use mylist[:]
again. =) It's poor syntax.
It just returns the entire list. so just use the name of the list mylist
. By adding the brackets, you forced finding og the global var, and created your problem
Upvotes: 0