1

I am trying to to append current to master every time current changes. I have been unsuccessful using list. I have been able to to modify strings and append different strings to master but it would be much easier if I could use list.

master = []

def recur(count,current):
    count = count + 1
    if (count == 5):
        return
    current.append(1)
    master.append(current)
    recur(count,current)


recur(0,[])

print(master)
# out put
# [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]

# what I expected
# [[1], [1,1], [1,1,1], [1,1,1,1]]
Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
thegib50
  • 13
  • 2
  • Can you explain *why* you expected what you expected? – Scott Hunter Jan 18 '20 at 16:31
  • Does this answer your question? [How to allow list append() method to return the new list](https://stackoverflow.com/questions/12902980/how-to-allow-list-append-method-to-return-the-new-list) – mkrieger1 Jan 18 '20 at 16:33
  • 1
    Alternatively, https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly – mkrieger1 Jan 18 '20 at 16:34
  • 1
    Just use `master.append(current.copy())`. To understand more about the issue, refer [this](https://stackoverflow.com/questions/240178/list-of-lists-changes-reflected-across-sublists-unexpectedly). – Ajay Dabas Jan 18 '20 at 16:40
  • 1
    As an aside, it might be best to avoid recursion for this. – AMC Jan 18 '20 at 16:45
  • @thegib50 check the answer I posted it might help you understand the problem. Please visit the visualization link I posted. – Ch3steR Jan 18 '20 at 17:45

3 Answers3

2

This is what you want:

master = []

def recur(count, current):
    count += 1
    if (count == 5):
        return

    new_current = current.copy()

    new_current.append(1)
    master.append(new_current)

    recur(count, new_current)


recur(0, [])

print(master)

The issue is that current is a reference to the list object... not the actual list itself. So when you append current to master you are just appending a reference to the same list object. So when you add a new element to the current list it's added to the one list that all of your references are pointing to.

The solution is to take a copy of current list to store its state at that time. There are different types of copy - deep and shallow. Shallow would make a copy of the list object but not it's elements, a deep copy will recurse through the elements and any subelements if you have a list of lists for example.

James McCorrie
  • 2,283
  • 3
  • 18
  • 22
0

Try the code below,

master = []

def recur(count, current):
    count += 1
    if (count == 5):
        return
    tmp = current[:]
    tmp.append(1)
    master.append(tmp)
    recur(count, tmp)

recur(0, [])

master

output

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]
Shibiraj
  • 769
  • 4
  • 9
0

The reason is you are appending the reference of the current list to master. So, every time you change current the previously appended lists also change.

Use this link for visualization:click here

enter image description here

>>>def recur(count,current):
    count = count + 1
    if (count == 5):
        return
    current.append(1)
    master.append(current)
    recur(count,current)


>>> master=[]
>>> recur(0,[])
>>> master
[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]
>>> for i in master:
    id(i)


2485591104264
2485591104264
2485591104264
2485591104264
>>> 

Method 1

You can try this. There is no need to keep track of the current list you are appending to master.

def recur(count):
    count+=1
    if count==5:
        return
    curr=[1]*count
    #print(curr)
    master.append(curr)
    recur(count)
master=[]
recur(0)
print(master)

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]

Method 2

If you are keen on using current then try this. Visualization for this code click here.

Image 2

def recur(count,curr):
    count+=1
    if count==5:
        return
    curr.append(1)
    master.append(curr)
    recur(count,curr[:])
master=[]
recur(0,[])
print(master)

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]

Method 3

Or you can try this.

def recur(count,curr):
    count+=1
    if count==5:
        return
    curr.append(1)
    master.append(curr[:])
    recur(count,curr)
master=[]
recur(0,[])
print(master)

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]

Method 4

If you want to return [[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]] then try this.

def recur(count,curr):
    count+=1
    if count==5:
        return []
    curr.append(1)
    return [curr]+recur(count,curr[:])
master=recur(0,[])
print(master)
another_master=recur(0,[])
print(another_master)

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]

[[1], [1, 1], [1, 1, 1], [1, 1, 1, 1]]
Ch3steR
  • 20,090
  • 4
  • 28
  • 58