1

I am new to Python, therefore my question will look like pretty foolish. I try to make some program that makes two-dimensional array. One function puts items to list and returns an array. Then, second function put results of the first function and puts it in outer list. My program looks like this:

def get_matrix():
    d = some_dict
    matrix = list()
    while len(matrix)<3:
        row = get_row(d)
        matrix.append(row)
    return matrix

def get_row(dict):
    array = list()
    for t in range(3):
        a = dict.popitem()
        array.append(a)
    return array

some_dict = dict()

for x in range(9):
    some_dict[x] = "a"+str(x)

print(some_dict)

print(get_matrix())

It works well. But what if I want not to change list d in outer function but just do it so:

def get_matrix():
    d = some_dict
    matrix = list()
    while len(matrix)<3:
        row = get_row(d)
        matrix.append(row)
        for x in row:
            d.pop(x)
    return matrix

In other words, I want to keep the whole dict in outer function. Actually I want know why the outer values change if we change only the dict given by arguments of inner function?

hopheylalaley
  • 69
  • 1
  • 10

1 Answers1

2

You are popping items of the dict in the inner function. Since you are passing a handle to a mutable object (dict) to your get_row() function, the popping will effect the dict in the outer get_matrix as well.

Note that a dict as a complex object behaves differently in that regard than an immutable parameters (int, float, str, etc.). Their values remain unchanged.

You could pass a copy of your dict

row = get_row(copy.deepcopy(d))

as explained here: Understanding dict.copy() - shallow or deep?. Btw, you can access the values in your dict without popping them

def get_row(dict):
    ...
    for t in range(3):
         ...
         # a = dict.popitem()
         a = dict[t] 

which will also leave the dict unharmed.

Community
  • 1
  • 1
user2390182
  • 72,016
  • 6
  • 67
  • 89
  • 1
    There's no such thing as "complex" nor "primitive type" in Python, everything is an object. What makes floats, ints or string "behave" differently is that they are immutable. Since they are immutable, you cannot change them (yeah...), neither in the callee NOR in the caller - thy are immutable, period. – bruno desthuilliers Nov 25 '15 at 18:08
  • You are right - I have edited my answer accordingly. – user2390182 Nov 25 '15 at 19:32