0
  1. Why doesn't the function x modify the contents of the list that is passed to it?
  2. How can I change the MWE so that x does modify the contents of the list that is passed to it?
>>> def x(mylist):
...     mylist = [ x for x in mylist if x > 5 ]
... 
>>> foo = [1,2,3,4,5,6,7,8,9,10]
>>> x(foo)
>>> print foo
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1
  • 3
    mylist = makes mylist point to a different list. Commented Dec 6, 2015 at 19:40

2 Answers 2

6

The function doesn't modify x because it is reassigning the name mylist to a new value. The alternative to this would be surprising.

a = 1
b = a
b = 2
assert a == 1 # would you want a to be 2 here?

If you want to replace the contents you can do so with a slice assignment

def x(mylist):
    mylist[:] = [ x for x in mylist if x > 5 ]

The assignment operator in python doesn't go into any method calls. It is the mechanism for name rebinding. However, you can implement the __setitem__ method (as list does), which is more or less the operator []=

With slice assignment you are calling __setitem__ with a slice argument that says "replace this slice of the list with ..." where ... is the right side of the =

Sign up to request clarification or add additional context in comments.

4 Comments

I'm confused. In Python, I thought that a=1 creates a reference to 1, and then b=a creates another reference to the same 1, so that then executing b=2 would in fact change the value of the object (the 1) referred to by a. Can you please help me see my error?
@synaptik why would you think that? Particularly with immutable objects like integers, even a trivial example would disabuse you of that.
You are correct in the first two steps but b = 2 makes b reference a different object with the value 2 rather than modifying the 1 in memory.
When you say b = a you are saying "make b point to whatever a points to." When you say b = 2 you are saying "make b point to 2" not "change what b is already pointing to, to be 2"
1

As Ryan Haining explained, x is reassigning the list. It should, however, only modify the list items:

def x(mylist):
    for i in reversed(mylist):
        if not i > 5:
            mylist.remove(i)

Note that you should traverse the list in reversed order.

Comments

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.