0

I need to a function that would reset the list to its orginal state so in order to do that I would use the copy of a list as its the most straightforward way to achieve it.

Every time I make changes to a list(or number of lists) I would like to have a list in its orginal state. Since the number of lists can be bigger I need a function that can deal with it without repating several lines of code everytime.

I tried to make a function that would simply create a copy of a list and thus I could use it to get a a copy of orginal list for further alterations. But there is something that I am missing because im getting error:

list1=[1,2,3]
list2=['a','b','c']
list3=[434,52,43]

def copy_lists():
    list1c=list1[:]
    list2c=list2[:]
    list3c=list3[:]

copy_lists()
list1c.append('b')
copy_lists()
#now list1c should be back to orginal 
print(list1c)


---------------------------------------------------------------------------
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-5-95468ead1e78> in <module>()
      9 
     10 copy_lists()
---> 11 list1c.append('b')
     12 copy_lists()

NameError: name 'list1c' is not defined
Alex T
  • 3,529
  • 12
  • 56
  • 105
  • ` list1c` is a local variable, only defined inside `copy_lists`. – Eric Duminil Oct 17 '17 at 21:38
  • 1
    Deepcopy will probably do that for you: https://docs.python.org/3.6/library/copy.html – L. MacKenzie Oct 17 '17 at 21:38
  • Don't (try to) use so many global variables. Take the lists to copy as arguments, and return the copies in a tuple (or another list). – chepner Oct 17 '17 at 22:00
  • Can you [edit] this to make it more obvious to a casual reader why it isn't a duplicate of [How to clone or copy a list](https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list)? – Charles Duffy Oct 17 '17 at 22:34
  • I added that the main point here is that I needed a function that uses copy aspects of a list and that the function is causing the problem. – Alex T Oct 18 '17 at 11:58

1 Answers1

1

In python you have to be really careful when making copies of objects. If you do list1c = list1 and list1c.append('a') list1 will also have 'a' appended to it. Here is an article talking about when variables are pointers vs an actual copy of the data from another variable.

The best way to make sure that modifying a copy of an object will not change the original is to use the deepcopy function from the copy module.

from copy import deepcopy
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
list3 = [434, 52, 43]

list1c = deepcopy(list1)
list2c = deepcopy(list2)
list3c = deepcopy(list3)
list1c.append('a')

print(list1c)

# list1 will not be modified if you change list1c
print(list1)

The error you are running into now is a scoping problem. When you are trying to use list1c outside the copy_lists() function you are trying to access a local variable outside its scope (in this case the copy_lists function). Here is some reading about scoping in python.

If you would like to do the copying in a function here is a way to do it by returning a tuple from the copy_lists() function.

from copy import deepcopy

list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
list3 = [434, 52, 43]


# changed list1 to l1 to avoid having a variable in the inner scope shadow the outer scope
def copy_function(l1, l2, l3):
    l1c = deepcopy(l1)
    l2c = deepcopy(l2)
    l3c = deepcopy(l3)
    return l1c, l2c, l3c


list1c, list2c, list3c = copy_function(list1, list2, list3)
list1c.append('a')

print(list1c)

# list1 will not be modified if you change list1c
print(list1)
PeterH
  • 858
  • 1
  • 6
  • 15