4

I'm currently making my first project in Python - tic tac toe as i thought it would be a good place to start and I've finally hit a road block.

I've currently got the board setup as a list - Board = [1,2,3...,9] and to reset, Board's contents is deleted and re-entered by a separate list however it also adds the brackets.

Is there a way to grab the contents of a separate list without also grabbing the brackets?

if newGame == 'Y' or 'y':
     del Board[:]
     Board.append(startBoard)
     print Board #for testing
 else:
     sys.exit('game over')

What I'm getting is looking like this:

[[1,2,3,4,5,6,7,8,9]]
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Chirpas
  • 93
  • 1
  • 1
  • 4
  • Slightly off topic but variable names are conventionally lower_case/camelCase. See [pep8](https://www.python.org/dev/peps/pep-0008/). – Holloway Jan 26 '15 at 09:28
  • Possible duplicate: http://stackoverflow.com/questions/252703/python-append-vs-extend – GLHF Jan 26 '15 at 09:28
  • 2
    `if newGame == 'Y' or 'y'` will always be true. Use `if newGame =='Y' or newGame == 'y'` or `if newGame in ('y', 'Y)` or `if newGame.lower() = 'y'`. – Matthias Jan 26 '15 at 09:29

3 Answers3

17

Use extend.

Board.extend(startBoard)

Alternatively you can do:

Board = [el for el in startBoard]

and omit the del Board[:] althogether.

Alternatively you can use the copy module:

Board = copy.deepcopy(startBoard)

For me the best will be this though:

Board = [i+1 for i in xrange(9)]

Or the simpler:

Board = range(1, 10) # python 2

or

Board = list(range(1, 10)) # python 3

As zehnpaard suggested in the comments.

Also you can do what Erik Allik has proposed in his answer.

Community
  • 1
  • 1
dmg
  • 7,438
  • 2
  • 24
  • 33
  • The second one may cause issues if there are other references to Board that also need to be updated. Also it would be simpler to do startBoard[:] instead of using a list comprehension. – zehnpaard Jan 26 '15 at 09:30
  • The only reason I dislike the `[:]` is that it makes a shallow copy. For `int`s it's OK, but for complex objects it just won't do. Not that any other than `deepcopy` will. – dmg Jan 26 '15 at 09:37
  • if you find yourself needing deepcopy more than rarely, you should consider a rethink :) – Erik Kaplun Jan 26 '15 at 09:42
  • Right, frankly copying objects with mutable state always requires a fair bit of care... If I may quibble one last time (I promise!) I think your last one would be simpler as `Board = range(1, 10)` in Python 2.x, or `Board = list(range(1, 10))` in Python 3.x. – zehnpaard Jan 26 '15 at 09:53
  • @zehnpaard Good point. I do have a thing for LCs, which is why I sometimes use that instead of the simpler `range` version. – dmg Jan 26 '15 at 09:56
  • `Board = [el for el in startBoard]` is a shallow copy as well. – njzk2 Jan 26 '15 at 18:20
0

if you want to clear out and modify the contents of a list in-place (as opposed to creating a new fresh list and assigning it back to the variable that holds your old list):

board[:] = startBoard

which, if nothing that needs to see the latest board contents points to the old list, is functionally equivalent to:

board = startBoard

you can get an idea of what it means to modify something in-place vs create a fresh copy/instance if you play around a little bit with assigning the same contents to multiple variables without making copies in the process.

Also, note that since startBoard in your case is a constant, you want to make sure nothing ever modifies it, so the 2nd example is really a very bad idea. There's also however a 3rd:

board = startBoard[:]

which is actually by far the best of all three. What it does is make a copy of startBoard and assign it to the variable board without ever modifying the old list board was pointing to. Also, because you're using a copy of startBoard, you can be sure your start board is always the same in the future.

Note that these aspects arise only in programming languages or styles where mutable datatypes are used; in Functional Programming, almost nothing ever gets modified so you can completely become ignorant of worrying about causing accidental adverse side-effect by touching something someone else is relying on.

Furthermore: note that copying a list can be done in a multitude of ways in Python; from a high level point of view which I'm currently speaking out for there is little difference though, so copy.copy(startBoard) is the same as [x for x in startBoard) is the same as startBoard[:] etc.

See also the PEP8 which provides you with useful coding conventions.

Erik Kaplun
  • 37,128
  • 15
  • 99
  • 111
0

Try this:

for x in startBoard:
    Board.append(x)
Luke Taylor
  • 8,631
  • 8
  • 54
  • 92