0
def deep_reverse(L) :
    for i in range (len(L)-1,-1,-1):
        L=L[::-1]
    for i in range (len(L)-1,-1,-1):
        L[i]=L[i][::-1]  

L = [[0, 1, 2], [1, 2, 3], [3, 2, 1], [10, -10, 100]]
deep_reverse(L) 
print(L)

So I have this code here and a function called deep_reverse(L). I am trying to mutate the list L, at the end when i print(L) it prints out L = [[0, 1, 2], [1, 2, 3], [3, 2, 1], [10, -10, 100]]. However, when I print from within the function, I get L= [[2, 1, 0], [3, 2, 1], [1, 2, 3], [100, -10, 10]], which is what I want. How can i permanently mutate L so that it stays that way when I print it outside the function.

Oskar
  • 1,371
  • 6
  • 19
  • 3
    Before you even start mutating the list, you might want to fix your indentation first. – baduker Jan 27 '21 at 22:35
  • 1
    This has already been answered here: https://stackoverflow.com/questions/31359652/how-to-mutate-a-list-with-a-function-in-python – SharpInnovativeTechnologies Jan 27 '21 at 22:50
  • Do you want the top-level list reversed? Your code seems to try to do it, but the list you say is what you want isn't reversed. It's not actually reversed because you reverse it an even number of times. – Barmar Jan 27 '21 at 23:42

4 Answers4

2

You're not mutating anything. The function creates a new list and assigns it back to the local variable, which has no effect on the caller's variable.

Also, your first for loop is repeatedly reversing L. If the list has an even number of elements, it will reverse it back to the original order.

Use slice assignment to modify the list in place.

def deep_reverse(L):
    L[:]=L[::-1]
    for i in range (len(L)-1,-1,-1):
        L[i][:]=L[i][::-1] 

Note also that your code only reverses two levels deep. Use recursion to handle any depth.

def deep_reverse(L):
    if isinstance(L, list):
        L[:] = L[::-1]
        for subL in L:
            deep_reverse(subL)
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 1
    The recursive option throws `TypeError: 'int' object is not subscriptable`. It might need a type check (or ducktype check) at the top. Also worth noting that the first option reverses the outer list as well as the inner lists, which is nice. But that's different from what OP has given as expected/wanted output. – aneroid Jan 27 '21 at 23:20
  • 1
    Fixed the recursion. You're right about what he said he expects, but since his code has `L = L[::-1]` I think he miswrote that. – Barmar Jan 27 '21 at 23:32
  • Added an answer based on yours. Perhaps a total deep reversal was what OP wanted but didn't know until they saw your solution :-) – aneroid Jan 27 '21 at 23:37
0

The problem is that by calling L = L[::-1] you allocate a new array for L and do not overwrite the one you passed on to the function. In order to do this you need to use assign the new value as L[:] = L[::-1].

Thus your function becomes:

def deep_reverse(L):
    L[:] = L[::-1]
    for i in range (len(L)-1,-1,-1):
        L[i] = L[i][::-1]


L = [[0, 1, 2], [1, 2, 3], [3, 2, 1], [10, -10, 100]]
deep_reverse(L) 
print(L) # [[100, -10, 10], [1, 2, 3], [3, 2, 1], [2, 1, 0]]

Furthermore, I assumed you wanted the single elements to be reversed, so you don't need the first for loop.

Oskar
  • 1,371
  • 6
  • 19
0

It as simple as do this - it's to minimize the changes of your code: (remove first loop- since no effect; and add return statement) all in-placed change.

def deep_reverse(L):
    for i in range(len(L)-1, -1, -1):
        L[i] = L[i][::-1]
        
    return L


L = [[0,1,2], [1,2,3], [3,2,1], [10,-10,100]]

LL = deep_reverse(L)

print(LL)  # [[2, 1, 0], [3, 2, 1], [1, 2, 3], [100, -10, 10]]
Daniel Hao
  • 4,922
  • 3
  • 10
  • 23
0

You've said that if L = [[0, 1, 2], [1, 2, 3], [3, 2, 1], [10, -10, 100]] you
want the result L = [[2, 1, 0], [3, 2, 1], [1, 2, 3], [100, -10, 10]].

Based on Barmar's answer, you can do this:

def deep_reverse(L):
    for subL in L:
        subL[:] = subL[::-1]


>>> L = [[0, 1, 2], [1, 2, 3], [3, 2, 1], [10, -10, 100]]
>>> deep_reverse(L)
>>> L
[[2, 1, 0], [3, 2, 1], [1, 2, 3], [100, -10, 10]]
aneroid
  • 12,983
  • 3
  • 36
  • 66