-2

Hey (: I have to rewrite the code to return a mutated list

original code of the function

def times(l, n) :
    l_original = l
    
    for i in range(2, n+1) :
        l_original = l + l_original
    
    return l_original

my attempt to make it mutated:

def times_mut(l,n): 
    l1= l
    for _ in range(2,n-1):
        l.extend(l1)
l = [1,2,3]
times_mut(l,6)
print(l)

So my idea was to change the orignal list over and over or how exactly do I change the list into a mutated one ?

The expected output should be l*n.

oneIphone
  • 7
  • 2

1 Answers1

2

Firstly, it's good practice in Python to mutate OR return, but not both. That said, you were correct to remove the return.

Secondly, the problem here is how you use extend, which mutates the list along with l1, which is the copy of your original list.

If you run your code and print l1 in the loop for debugging:

def times_mut(l,n): 
    l1= l
    for _ in range(2,n-1):
        print(l1) # debugging
        l.extend(l1)
l = [1,2,3]
times_mut(l,6)
print(l)

You will see that l1 changes like so:

[1, 2, 3]
[1, 2, 3, 1, 2, 3]
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

even though you don't actually change it. That's because l1 is a "shallow" copy of l, meaning that it points to the same place in memory. As a result, any change you make on l it will also appear in l1.

Why does this not happen in the original code? Because l_original = l + l_original creates a new list and stores is in the local variable l_original while the built-in functions like extend, append etc mutate the object.

I would advise that you look at this, this, this and this.


Furthermore, a simple solution would be to use copy.deepcopy, which basically copies the content of l and stores it on a new memory space like so:

import copy

def times_mut(l,n): 
    l_original=copy.deepcopy(l)

    for iii in range(2,n+1):
        l.extend(l_original)

l = [1,2,3]
times_mut(l,6)
print(l)

output:

[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
Nikolas
  • 46
  • 5