0

I am trying to write a code for a number of integer partitions and I have it down, checking my temporary variables my code is executing properly; however, I am encountering a strange bug where my master list (lst) gets updated when my temporary list (temp) gets updated. I am writing temp into lst, but that shouldn't change the values in lst later if temp gets updated.

This is my entire code (as an example n = 5)

def partitions(n):
'''define a function which returns the number of integer partitions of n'''
flag = True
lst = []
lst.append(n)
while flag:
    if isinstance(lst[len(lst)-1], list):
        temp = lst[len(lst)-1]
    else:
        temp = [lst[len(lst)-1]]
    place = len(temp) - 1
    i = 2
    while i > 1:
        for j in reversed(temp):
            if j > 1:
                i = 1
                temp[place] = temp[place] - 1
                if place < len(temp) - 1:
                    temp[place+1] = temp[place+1]+1
                else:
                    temp.append(1)
            print("before changing place", lst)
            place = place - 1
        i = 1
        if temp[0] != 1:
            lst.append(temp)
        else:
            flag = False
print(lst)
return len(lst)

The output from this for n = 5 should be lst = [5, [4,1],[3,2],[3,1,1],[2,2,1],[2,1,1,1],[1,1,1,1,1]] and len(lst) = 7.

The error occurs when I am updating temp from [4,1][3,2]. When I update temp it also mirrors that in lst, even though I am NOT updating lst in any way until I append. Here is the output from my print statements:

before changing place [5]
before changing place [5, [4, 1]]
before changing place [5, [3, 2]]
before changing place [5, [3, 1, 1], [3, 1, 1]]
before changing place [5, [2, 2, 1], [2, 2, 1]]
before changing place [5, [2, 2, 1], [2, 2, 1], [2, 2, 1]]
before changing place [5, [2, 1, 2], [2, 1, 2], [2, 1, 2]]
before changing place [5, [1, 2, 2], [1, 2, 2], [1, 2, 2]]
[5, [1, 2, 2], [1, 2, 2], [1, 2, 2]]`

I guess I am just confused about how a list should behave when you append a variable.

rici
  • 234,347
  • 28
  • 237
  • 341
  • 1
    Because you keep appending *the same list*. – juanpa.arrivillaga Apr 08 '17 at 21:40
  • 1
    ``temp`` points to a reference (of an item in ``lst``), what you want is to create a copy. – Mike Scotty Apr 08 '17 at 21:41
  • Essentially, when you assign something, `temp = ` it's not creating a copy. `temp` is now a name referring to ``, but anything else still referring to `` will still see the effects of mutating `temp`, e.g. `temp.append()` will have the same effect of `.append()` – juanpa.arrivillaga Apr 08 '17 at 21:42
  • 1
    Also, please read [this](https://nedbatchelder.com/text/names.html) article written by SO legend, Ned Batchelder on how Python names/variables work. – juanpa.arrivillaga Apr 08 '17 at 21:44
  • Thanks very much for the answers everyone. @juanpa.arrivillaga thanks for the article, very enlightening. I didn't know that lists behaved so much differently than common variables. – Nicholas Smith Apr 09 '17 at 18:08
  • @NicholasSmith What? No, lists behave *exactly* like everything else in Python... – juanpa.arrivillaga Apr 09 '17 at 18:22

0 Answers0