Python Forum
Append only adding the same list again and again - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Append only adding the same list again and again (/thread-27687.html)



Append only adding the same list again and again - viraj1123 - Jun-17-2020

Hi, I'm facing this really weird issue.I've been appending different lists to my list but while i print the result it shows that the last value appended is only added as many times as I appended different lists. My code and output will clear out exactly what I meant.
Here is my code:
def generate_MagicSquare(n):
    mat=[[0 for i in range(n)]for i in range(n)]
    i,j=n//2,n-1
    mat[i][j]=1
    number_inserted=1
    a=n**2
    while number_inserted<a:
        i,j=i-1,j+1
        if i==-1 and j==n:
            i,j=0,n-2
        elif i==-1 or j==n:
            if i==-1:
                i=n-1
            if j==n:
                j=0
        else:
            pass
        if mat[i][j]!=0:
            j-=2
            i+=1
        number_inserted+=1
        mat[i][j]=number_inserted
    return mat

def rotate_Clockwise_90(B):
    n1=len(B[0])
    for i in range(n1//2):
        for j in range(i,n1-i-1):
            temp=B[i][j]
            B[i][j]=B[n1-1-j][i]
            B[n1-1-j][i]=B[n1-1-i][n1-1-j]
            B[n1-1-i][n1-1-j]=B[j][n1-1-i]
            B[j][n1-1-i]=temp
    return B

x=[]
mat=generate_MagicSquare(3)
print(mat)
x.append(mat)
print(x)
a=rotate_Clockwise_90(mat)
print(a)
x.append(a)
print(x)
b=rotate_Clockwise_90(a) #Rotate by 180
print(b)
x.append(b)
print(x)
Output:
Output:
[[2, 7, 6], [9, 5, 1], [4, 3, 8]] [[[2, 7, 6], [9, 5, 1], [4, 3, 8]]] [[4, 9, 2], [3, 5, 7], [8, 1, 6]] [[[4, 9, 2], [3, 5, 7], [8, 1, 6]], [[4, 9, 2], [3, 5, 7], [8, 1, 6]]] [[8, 3, 4], [1, 5, 9], [6, 7, 2]] [[[8, 3, 4], [1, 5, 9], [6, 7, 2]], [[8, 3, 4], [1, 5, 9], [6, 7, 2]], [[8, 3, 4], [1, 5, 9], [6, 7, 2]]] Process finished with exit code 0

I think it has something to do with memory addresses, but don't have a good idea about it.
Any suggestions will be very helpful.
Thank you!


RE: Append only adding the same list again and again - bowlofred - Jun-17-2020

This is because your functions like rotate_clockwise_90 isn't returning a copy of the list, it's modifying the list and then handing it back. So you only have one list that you're modifying over and over again. And your big list just has that one appended multiple times.

You should decide if your functions should be returning copies, or if they should be modifying the passed-in function. Then either the caller or function can be making a copy.

outer_list = []
sublist = ['a']   # list brackets here make a new list
outer_list.append(sublist)
sublist[0] = 'b'  # modifying an element of the list, not a new list
outer_list.append(sublist)
print(outer_list)

# If you don't want to modify the passed-in list, make a copy
sublist = sublist.copy()
sublist[0] = 'c'  # This is modifying only the new list, not the old one
outer_list.append(sublist)
print(outer_list)
Output:
[['b'], ['b']] [['b'], ['b'], ['c']]



RE: Append only adding the same list again and again - viraj1123 - Jun-17-2020

Thank you very much for your response. But I couldn't clearly understand. If possible could you please edit my code so that I can get a proper understanding of what's happening.


RE: Append only adding the same list again and again - bowlofred - Jun-17-2020

Let me try a different way.

Line 37 creates a new square, and line 39 puts a link to that square into x.
Line 41 is the interesting bit. rotate_clockwise_90 is handed the square and it changes it. This change affects the reference to it in x. So x changes.
Line 43 then puts another link to the square in x. But this is the same link so all the elements in x are identical.

I think a good approach here is to make your functions not modify the data that is passed in That's easily done by making a copy early in the function. This approach is less memory efficient and would be a drawback for larger and more complex manipulations. But it does make them feel more like functions, where you don't expect the input to be modified.

For instance consider changing
def rotate_Clockwise_90(B):
    n1=len(B[0])
    ...
to

import copy
[...]
def rotate_Clockwise_90(B):
    B = copy.deepcopy(B)
    n1=len(B[0])
    ...
It's not the only way to go. You could instead make the copies in the main logic, allowing the functions to continue modifying the data. Either way is a possible solution.


RE: Append only adding the same list again and again - viraj1123 - Jun-17-2020

That works. Thank you very much. Learnt a new thing today!