M00000001
M00000001

Reputation: 309

Pass a List into Python Function

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

Answers (3)

felipe
felipe

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:

  1. The 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
  1. The 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

erncncbk
erncncbk

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

VISQL
VISQL

Reputation: 2048

(Don't use the [:] thing. That's horrible.)

My informal answer

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

Related Questions