Dan
Dan

Reputation: 1

Python reset items in a list to their initial values

I have several lists of lists, and I want to be able to edit the items in the lists throughout my code, and then reset them all to their initial values later.

Here's an example:

list_a = [0, 1, 2]
list_b = [list_a, 3, 4]
list_c = [6, 7]
list_d = [8, 9]
lists = [0, list_b, 5, list_c, list_d]
#As you can see, lists are of varying length, and sometimes nested multiple times.

print(lists)
Out>>> [0, [[0, 1, 2], 3, 4], 5, [6, 7], [8, 9]]

#Currently, I'm saving the important items of "lists" in the first item, like this:
lists[0] = lists[1:]

#Then I edit the values of various items, like this:
lists[1][0][2] = 0
lists[2] = 0
lists[3][1] = 0
lists[4][1] = 0

print(lists[1:])
Out>>> [[[0, 1, 0], 3, 4], 0, [6, 0], [8, 0]]

#Then I try to reset those values to the originals that I stored in lists[0]
lists[1:] = lists[0]

print(lists[1:])
Out>>> [[[0, 1, 0], 3, 4], 5, [6, 0], [8, 0]]

As you can see, this method works for list[2] because that item is a value, and not a nested list. It seems that even though I use [1:] to make a copy in lists[0], the references to nested lists are what get copied, rather than the values in those nested lists.

How can I properly copy the values of lists[1:] into lists[0] and then back again, without having both copies reference the same index?

Or perhaps there's a simpler way to achieve the same intended result, returning all items in lists to their original values?

Upvotes: 0

Views: 2197

Answers (2)

Jean-Paul Calderone
Jean-Paul Calderone

Reputation: 48335

Use persistent data structures. Avoiding mutation allows greater sharing and avoids spooky action at a distance like this.

For example:

>>> from pyrsistent import pvector
>>> list_a = pvector([0, 1, 2])
>>> list_b = pvector([list_a, 3, 4])
>>> list_c = pvector([6, 7])
>>> list_d = pvector([8, 9])
>>> lists = pvector([0, list_b, 5, list_c, list_d])
>>> print(lists)
pvector([0, pvector([pvector([0, 1, 2]), 3, 4]), 5, pvector([6, 7]), pvector([8, 9])])
>>> lists = lists.set(0, lists[1:])
>>> lists = lists.transform([1, 0, 2], 0)
>>> lists = lists.transform([2], 0)
>>> lists = lists.transform([3, 1], 0)
>>> lists = lists.transform([4, 1], 0)
>>> print(lists[1:])
pvector([pvector([pvector([0, 1, 0]), 3, 4]), 0, pvector([6, 0]), pvector([8, 0])])
>>> lists = lists[:1] + lists[0]
>>> print(lists[1:])
pvector([pvector([pvector([0, 1, 2]), 3, 4]), 5, pvector([6, 7]), pvector([8, 9])])
>>>

Also, Python has non-list variables. The first element of a list of random values is a strange place to "save" things. Given the above, you could just keep the original values around in another variable. For example:

>>> list_a = pvector([0, 1, 2])
>>> list_b = pvector([list_a, 3, 4])
>>> list_c = pvector([6, 7])
>>> list_d = pvector([8, 9])
>>> lists = original = pvector([list_b, 5, list_c, list_d])

Now you can screw around with lists and when you get tired of it, lists = original brings you right back to the initial state.

Upvotes: 0

Max Paymar
Max Paymar

Reputation: 708

Use deep copy: https://docs.python.org/3/library/copy.html

This will copy the object as well the child objects.

Upvotes: 1

Related Questions