python list mutation in loops, global modifying vs. local modifying -


halp, perhaps more experienced python can answer (noobish) question.

i'm having trouble figuring out why following behavior occurs lists.

let's have following functions:

def foo1(l):    """     l list    """    l = ['new', 'stuff']    print l  def foo2(l):    """     l list    """    l[:] = ['new', 'stuff']    print l 

idle outputs following:

>>>l = [1,2,3]   >>>foo1(l)   ['new', 'stuff']   >>>l   [1,2,3]    >>>foo2(l)   ['new', 'stuff']   >>>l   ['new', 'stuff'] 

i can't figure out why first function temporarily modifies list, second modifies list globally. don't think it's scope issue, rather issue l= versus l[:]=

i know if use list comprehension change l or use l.append() or other method mutate l within function, modifies l globally, too.

i'm not new python, but, usually, google solutions problems when coding, and, if works, don't question it. i'm taking time summer learn best-practices , @ meat of python.

edits: martijn decided mark question duplicate, disagree. linked question not address question.

when variable passed function, function creates new environment own scope. variables in environment exist in scope of environment, , else. hence, when list l passed both foo1 , foo2, temporary list, l, made within scope of function call. in other words, prior calling foo1(l), there exists list named l equal [1,2,3]. after call foo1(l), new function environment made, , contains temporary list, called l, lives in scope of function. if modify l via l = [blah, blah, blah] within function, nothing happens original list l. however, using [:] on l within function, original list modified. why? how python know after has created temporary variable limited scope, needs modify original 1 global scope? concept not make sense me.

both argument l , global variable l refer same objects in memory. when pass object reference global object since how references , assignment work in python. when ['new', 'stuff'] in foo1 assign value l local copy i.e. argument since first lookup assignment. on doing l[:] = ['new', 'stuff'] in foo2 doing slice affects global variable.

you can test checking id same both global , parameter l.

l = [1, 2, 3]  b = l  id(b) == id(l)    # true  def foo(l):    print(id(l) == id(b))  foo(l)    # true  # or..  def foobar(l):     print(id(locals()['l']) == id(globals()['l'])) 

hope helps. :)


Comments

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -