2
#!/usr/bin/env python

def modify_dict():

    d['two'] = 2

d = {'one':1}

modify_dict()

print d

I get

$ ./globaltest.py 
{'two': 2, 'one': 1}

I was hoping to see only {'one':1} since d is not declared global within the function. Why did d get both key-value pairs ?

3
  • 2
    Because d is mutable and the operation you performed on d inside dictionary is not be considered as an assignment operation by functions. For example with lists(mutable object) += operator will raise error in function body, but .append and .extend and assignment by index will work fine. Commented Sep 18, 2014 at 6:07
  • 2
    To expand - when you assign (x = y) to a variable inside a function, python implicitly decides you're referring to a local. The syntax d[k] = x resolves to a __setitem__ call - so while it looks syntactically like assignment, it is not. Commented Sep 18, 2014 at 6:20
  • Does this answer your question? Why is the global keyword not required in this case? Commented Feb 22, 2021 at 3:19

3 Answers 3

3

Python search for variables is based on the LEGB rule:

Local, Enclosing functions, Global, Built-in

When you call your function it tries to find a variable named d, and will find in global scope since you created d before calling the function. And since d is mutable, it will get updated.

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

Comments

3

Take a look at the data model of python. Dictionaries and lists are mutable objects, which is why globally defined dictionaries for example do not need to be declared global. Their contents may be changed at any time.

To understand mutability, think of the strings in python. They are an immutable object. You can for example replace the contents of a given string but in doing so the interpreter creates a new string object, and thus gives this string object a new identity (and thus a memory address).

>>> s = "foo"
>>> id(s)
140202745404072
>>> s = "bar"
>>> id(s)
140202745404112

I've answered a few similar questions before, so take a look if you can find more information from them.

Comments

2

In a quick workaround is copy dictionary in local scope of the function.

import copy

d = {'one':1}

def modify_dict():
    local_d = copy.deepcopy(d)
    local_d['two'] = 2
    print local_d

modify_dict()
print d

you will see output following :

>>>{'two': 2, 'one': 1}
>>>{'one': 1}

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.