On Wed, Apr 23, 2014 at 04:46:49PM -0700, Denis Heidtmann wrote: > In a coursera python course video the following code was presented: > > a = [4,5,6] > > def mutate_part(x): > a[1] = x > > mutate_part(200) > > The presenter said something like "a is a global variable, so a becomes > > [4,200,6] after running mutate_part(200)." > > Indeed it does, but why does this work without specifying a as global > within mutate()? > My thinking was that an "undefined" error should have been raised.
You only need to define variables as global if you assign to them: def function(x): global a a = [1, 2, 3, x] # assignment to variable "a" The preferred name for this sort of assignment is "name binding", where you bind a value (in this case, the list [1, 2, 3, x]) to the name "a". You only need to declare variables as global when you perform a name binding on that variable. Merely retrieving the existing value of a variable doesn't count as a binding, and doesn't need to be declared: # This is okay def function(): n = len(a) # This is not needed def function(x): global len # Yes, built-in functions are variables too! global a n = len(a) and that would be too painful for words.[1] Now, let's go back to your function: def mutate_part(x): a[1] = x It looks like a name binding (an assignment) to a, but look more closely: you're not actually binding to the name "a", you are binding to the item *inside* a. After calling "a[1] = x", a remains bound to the same list as before, it is just that the list has been modified in-place. So this does not count as a name binding operation, and no global declaration is needed. The same applies to mutating dicts in place, or setting attributes. These are all examples of in-place modifications: some_dict.clear() some_list.sort() obj.attribute = 23 some_dict[key] = value del some_list[0] Only actual assignments to the bare name, including deleting the name, need a global declaration: some_dict = {} some_list = [1, 2, 3] obj = something() del some_list [1] For advanced users: built-ins aren't technically "global", they actually live in a separate namespace called "builtins" or "__builtin__" depending on the version of Python you use. But the principle is the same. -- Steven _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: https://mail.python.org/mailman/listinfo/tutor