Reputation: 4435
it seems that strings and dicts behave fundamentally differently in python. when i pass a string to a function it gets modified in the local function's scope only, but when i do the same with a dict, it gets modified in the scope beyond the function:
def change_str(s):
s += " qwe"
def change_arr(a):
a[1] = "qwe"
ss = "asd"
change_str(ss)
print ss
# prints:
# asd
aa = {0:"asd"}
change_arr(aa)
print aa
# prints:
# {0: 'asd', 1: 'qwe'}
is this behavior intentional, and if so then why?
Upvotes: 1
Views: 213
Reputation: 24788
Don't let the 'assignment' operator fool you. This is what is really going on in each of these functions:
def change_str(s):
# operation has been split into 2 steps for clarity
t = s.__iadd__("qwe") # creates a new string object
s = t # as you know, without the `global` keyword, this `s` is local.
def change_arr(a):
a.__setitem__(1, "qwe")
As you can see, only one of these functions actually has an assignment operation. The []=
is shorthand for (or equivalent to) .__setitem__()
.
Upvotes: 1
Reputation: 251353
Yes, it's intentional. Each type determines how operators work on it. The dict type is set up so that a[1] = "qwe"
modifies the dict object. Such changes will be seen in any piece of code that references that object. The string type is set up so that s += "qwe"
does not modify the object, but returns a new object. So other code that was referencing the original object will see no changes.
The shorthand way of saying that is that strings are immutable and dicts are mutable. However, it's worth noting that "dicts are mutable" isn't the whole reason why the behavior happens. The reason is that item assignment (someDict[item] = val
) is an operation that actaully mutates a dict.
Upvotes: 1
Reputation: 12077
It is intentional behavior. Strings are immutable in python, so essentially all string operations return a new string and as your functions do not return anything, you cannot see the new string asd qwe
. You can change the contents of mutable containers outside of local scope without declaring them global.
You can read more about mutable types in the official documentation of pythons data model.
Upvotes: 5