1

Why does python not support mylist being redefined to [7,7,7,7] and having it propagate back to main(). But it does support it if I were to change each index to 7 like mylist[0] = 7 would make the second print statement [7,2,3,4]

def changes(mylist):
    mylist = [7,7,7,7]

def main():
    mylist = [1,2,3,4]
    print (mylist)
    changes(mylist)
    print (mylist)

main()

It would work if I used this

def changes(mylist):
    for x in range(len(mylist)):
        mylist[x] = 7

def main():
    mylist = [1,2,3,4]
    print (mylist)
    changes(mylist)
    print (mylist)

main()
StryXe
  • 13
  • 4
  • 2
    You could read about how Python references work. `mylist = [7,7,7,7]` does NOT redefine the list, it creates a new list (the old one still exists) and points the local variable `mylist` to it (which is NOT the same variable as `mylist` from the outter scope). – Ralf Oct 16 '19 at 19:31
  • *variables* are neither mutable nor immutable (or rather, *variables* are *always* mutable depending on how you look at it). Objects are mutable or immutable. And *assignment* never mutates the object. you should just read https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Oct 16 '19 at 19:58
  • Essentially, what you are describing when you simply do `mylist = [7,7,7,7]` and expect the changes to be visible in the caller, that would be *call by reference* semantics, which **Python does not support** – juanpa.arrivillaga Oct 16 '19 at 20:03
  • This was not a duplicate of https://stackoverflow.com/questions/48192290/, which is about the *enclosing* scope (lexical scoping). This one is about pass-by-reference. If it were expected to modify the caller's vairables *directly, without passing them*, that would still be about the *calling* scope (dynamic scoping). – Karl Knechtel Sep 12 '22 at 10:55

2 Answers2

0

It's because the assignation in the function changes creates a new list with a scope limited to this function.

You can print the id of each object in order to see it easily:

def changes(mylist):
    print('argument mylist id: {}'.format(id(mylist)))
    mylist = [7,7,7,7]
    print('7, 7, 7, 7 list id: {}'.format(id(mylist)))

def main():
    mylist = [1,2,3,4]
    print (mylist)
    print('my list in main id: {}'.format(id(mylist)))
    changes(mylist)
    print (mylist)

main()
ndclt
  • 2,590
  • 2
  • 12
  • 26
0
def changes(mylist):
    mylist = [7,7,7,7]

In this code, mylist is a local variable. It is not visible outside the function. In the body of your function, you assign a list, but outside, this list is not visible.

You should return the new list, if you want to persist your changes. See this code:

def changes(mylist):
    mylist = [7,7,7,7]
    return mylist  # to persist the changes

So the rest of the codes will be:

def main():
    mylist = [1,2,3,4]
    print (mylist)
    mylist = changes(mylist)
    print (mylist)

main()
codrelphi
  • 1,075
  • 1
  • 7
  • 13