0

In my code, I have the nested list gamelist, defined as

gamelist = [['3'], ['2'], ['1']]

The purpose of the program is to treat the internal lists as stacks, appending smaller elements to stacks containing larger elements or empty stacks, sweeping up and down the list and not repeating moves. Theoretically this game should go:

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

And so on, until the list is sorted from smallest to largest.

In order to check the current move against previous moves, I created pastmoves, which has a copy of gamelist appended to it after each move.

pastmoves.append(gamelist[:])

So pastmoves should read

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

and so on after each consecutive move.

My issue is that while gamelist is being copied, the lists nested inside it are not, and pastmoves looks like this after two moves:

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

I'd like to make it so that all of the bottom-level values are also copies and remain static as gamelist changes. How can I achieve that?

user1576628
  • 792
  • 3
  • 8
  • 25

4 Answers4

2
from copy import deepcopy

pastmoves.append(deepcopy(gamelist))
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
1

Easiest way is just to use copy.deepcopy() to do a deep copy on the nested lists.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
1

As an alternative to copy.deepcopy(), here is how you can do this with a list comprehension:

pastmoves.append([inner[:] for inner in gamelist])

Note that this will only work for one level of nesting, if you have arbitrarily nested lists then copy.deepcopy() is definitely the way to go.

Andrew Clark
  • 202,379
  • 35
  • 273
  • 306
0

Simple: pastmoves.append( list(gamelist[:]) )

Now each time new object will bew generated

WBAR
  • 4,924
  • 7
  • 47
  • 81
  • That resulted in the same problem, I'm not sure why. – user1576628 Feb 25 '13 at 17:20
  • `list(gamelist)` will do the same thing as `gamelist[:]`, both are a shallow copy. `list(gamelist[:])` will just do a shallow copy twice and the inner lists of the result will have the same identity as the ones from `gamelist`. – Andrew Clark Feb 25 '13 at 17:42
  • My tests are showing kinda different results: >>> a = [[1],[2],[3]] >>> b = list(a) >>> a [[1], [2], [3]] >>> b [[1], [2], [3]] >>> b[1]=[8] >>> a [[1], [2], [3]] >>> b [[1], [8], [3]] – WBAR Feb 26 '13 at 09:19