If you assign something to the variable list_arg, it will from then on point to the new value. The value it pointed to before that assignment (your original list) will stay unchanged.
If you, instead, assign something to elements of that list, this will change the original list:
list_arg[:] = list(a)
This will make your code work as you wanted it.
But keep in mind that in-place changes are hard to understand and probably can confuse the next developer who has to maintain your code.
Answer from Alfe on Stack OverflowIf you assign something to the variable list_arg, it will from then on point to the new value. The value it pointed to before that assignment (your original list) will stay unchanged.
If you, instead, assign something to elements of that list, this will change the original list:
list_arg[:] = list(a)
This will make your code work as you wanted it.
But keep in mind that in-place changes are hard to understand and probably can confuse the next developer who has to maintain your code.
What I think you are asking is why after calling f(a), when f re-assigns the a you passed, a is still the "old" a you passed.
The reason for this is how Python treats variables and pass them to functions. They are passed by reference, but the reference is passed by value (meaning that a copy is created). This means that the reference you have inside f is actually a copy of the reference you passed. This again implies that if you reassign the variable inside the function. It is a local variable existing only inside the function; re-assigning it won't change anything in outside scopes.
Now, if you rather than reassigning the local variable/reference inside f (which won't work, since it's a copy) perform mutable operations on it, such as append(), the list you pass will have changed after f is done.
See also the question How do I pass a variable by reference? which treats the problem and possible solutions in further detail.
TL;DR: Reassigning a variable inside a function won't change the variable you passed as an argument outside the function. Performing mutable operations on the variable, however, will change it.
You have to return and assign the returned value to list1:
def func(list1):
list1 = list1[2:]
print(list1) # prints [2, 3]
return list1
list1=func(list1)
or you have to reference list1 as global inside func().
please goto http://www.pythontutor.com/visualize.html to visualize your code. It'll give you a more accurate explanation.
Here is a short explanation and two possible solutions for you question:
list1 = list1[2:]
This line creates a new list and assign it to local variable list1 in func namespace, while keeps the global one still.

If you want to change the original list:
Please use change in place methods(remove, pop etc) for list which can be found here.
Or you can return a new list like this:
def func(list1): list1 = list1[2:] print(list1) # prints [2, 3] return list1 list1 = [0, 1, 2, 3] list1 = func(list1) print(list1) # prints [2, 3]
Hope it helps.
Why do my lists get modified when passed to a function?
It seems that you can edit a global list in a function. (But you can’t edit a global variable. Without declaring global in the function) What’s the best practice for this list modification by a function ?
python - Modify list elements by passing it to a function - Stack Overflow
Modifying a list in a Python function - Stack Overflow
How can I modify a list inside a function in Python?
What is the difference between pass by reference and pass by value in Python?
Do you just modify the list without informing or you pass as parameter or return a modified list ?
(List bypass the function local scopes limitations)
is this what you are trying to accomplish?
def test(the_list):
for i in range(len(the_list)):
the_list[i] = the_list[i].lower()
the_list=["Python", "Programming"]
test(the_list)
print the_list
You can do that using a for loop, but it is much faster and more readable to use the bulit-in list comprehensions:
the_list=["Python", "Programming"]
the_list = [x.lower() for x in the_list]
print the_list
Python is pass by assignment for passing arguments inside the function. When you do
thisArray = thisArray[1:]
inside your function, you re-bind the passed argument to a new object created inside your function and proceed to mutate that copy created after slicing instead, rather than modifying your argument thisArray. To get the modified value, one way is to return this modified list from your function:
def reverse_this(thisArray):
saved_first = thisArray[0]
thisArray = thisArray[1:]
thisArray.reverse()
thisArray.insert(0,saved_first)
return thisArray
myList = ['foo', 1,2,3,4,5]
myList = reverse_this(myList)
print('after:', myList)
Other way is to modify the list's contents (assign to the slice) rather than re-binding the list itself:
def reverse_this(thisArray):
saved_first = thisArray[0]
thisArray[:] = thisArray[1:] # assign to the sliced list's contents
thisArray.reverse()
thisArray.insert(0,saved_first)
thisArray is re-assigned to a new list object by slicing, so any changes after that don't affect the original list passed into the function. Note the instance IDs of the lists:
def reverse_this(thisArray):
saved_first = thisArray[0]
print(f'thisArray pre-slice: {id(thisArray):#x}')
thisArray = thisArray[1:]
print(f'thisArray post-slice: {id(thisArray):#x}')
thisArray.reverse()
thisArray.insert(0,saved_first)
myList = ['foo', 1,2,3,4,5]
print(f'myList pre-call: {id(myList):#x}')
reverse_this(myList)
print(f'myList post-call: {id(myList):#x}')
print('after:', myList)
myList pre-call: 0x1e2f5713500
thisArray pre-slice: 0x1e2f5713500 # parameter refers to original list
thisArray post-slice: 0x1e2f5753800 # thisArray refers to new list
myList post-call: 0x1e2f5713500 # original list isn't changed.
after: ['foo', 1, 2, 3, 4, 5]
In Python, variables are names of objects. If you mutate an object, all names of that object "see" the change. A slice makes a new object, and in this case the name was reassigned to the new object.
To fix it, assign the slice into the full range of the original list, which mutates the original list instead of creating a new one:
def reverse_this(thisArray):
saved_first = thisArray[0]
thisArray[:] = thisArray[1:] # replace entire content of original list with slice.
thisArray.reverse() # thisArray still refers to original list here.
thisArray.insert(0,saved_first)
myList = ['foo', 1,2,3,4,5]
reverse_this(myList)
print('after:', myList)
after: ['foo', 5, 4, 3, 2, 1]
When assigning to a slice, a section of a list is replaced in place with another list. It doesn't necessarily have to be the same size.
Another example:
>>> s = list(range(10))
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(s)
2339680033664
>>> s[4:7] = [10,10] # replace indices 4 up to but not including 7
>>> s
[0, 1, 2, 3, 10, 10, 7, 8, 9]
>>> id(s) # id didn't change
2339680033664
Each item in a list has an associated index, starting from zero. As you probably know, you can access the items in the list using those indexes:
>>> magicians_names = ['Marv', 'Wowzo', 'Trickster', 'Didlo']
>>> magicians_names[0]
'Marv'
You can also modify the list items using those indexes:
>>> magicians_names[0] = 'Jerry Boomfang'
>>> magicians_names[0]
'Jerry Boomfang'
So what you need to do is loop through both the list and its indexes, modifying as you go. Which is exactly what the enumerate function is for.
>>> for index, magician in enumerate(magicians_names):
... magicians_names[index] += ' is great!'
...
>>> magicians_names
['Jerry Boomfang is great!', 'Wowzo is great!', 'Trickster is great!', 'Didlo is great!']
Hope this helps. The [:] retains the original list by making a copy or slice of the the original list to be used in the function being called. The exercises in the book are 8-9 to 8-11 on page 150 Crash course in Python.
def meta_mags(show_mags, great_mags):
"""(Change regular show magicians to Great magicians by moving them
to another list using a function meta_mags)"""
while show_mags:
change_mags = show_mags.pop()
# show the change from one list show_mags to great_mags
print("Great magicians: " + change_mags.title())
great_mags.append(change_mags)
def show_great_mags(great_mags):
"""Print --The Great--- after each great_mags magicians name"""
for great_mag in great_mags:
print(great_mag.title() +" The Great will be performing tonight !")
show_mags = ['alice', 'david', 'carolina']
great_mags = []
meta_mags(show_mags[:], great_mags)
show_great_mags(great_mags)
print(show_mags)
Your function can only return once, so you need to back it out of the for loop. As written, your function currently will return x after the first iteration, so none of the remaining elements are modified.
def double_list(x):
for i in range(0, len(x)):
x[i] = x[i] * 2
return x
An alternative, by the way, is to use a simple list comprehension, this will not modify the original list and will create a new one that you can assign back to the original variable if you'd like
def double_list(x):
return [i*2 for i in x]
>>> n = [3, 5, 7]
>>> n = double_list(n)
>>> n
[6, 10, 14]
If you prefer to modify the actual list argument, you can use change the function to
def double_list(x):
for index, value in enumerate(x):
x[index] = 2 * value
>>> n = [3, 5, 7]
>>> double_list(n)
>>> n
[6, 10, 14]
you can do it very easy with list comprehension.
n = [3, 5, 7]
def double_list(x):
return [y*2 for y in x]
print double_list(n)
'[6, 10, 14]'
You need to assign the returned list to your variable:
lis = zu(lis)
You have very carefully not mutated the original list in your function (by copying the list and mutating the copy), hence the need for an assignment. Alternatively, modify your function so that it does mutate the argument list.
lis=[[1,2],[3,4,5]]
def zu(l):
import copy
lcop=copy.deepcopy(l)
while True:
for i in range(len(lcop)):
lcop=copy.deepcopy(l)
for k in range(len(l[i])):
lcop[i].pop()
l=copy.deepcopy(lcop)
break
print l
return l
lis = zu(lis) # Here is the changes
print lis
But list is mutable in python so if you wanna modify the original list, just access the list inside the function without making a copy of it then it will change the original list you have outside, too.
for example
lis=[1,2,3]
print lst # print [1,2,3]
def zu(l):
l[0] = [5]
zu(lis)
print lis # print [5,2,3]