2

While understanding backtracking using 8 queens I came across an issue of list definition in python

def place(board, row, column):
 for c in range(column):
 if board[c]==row:
 return False
 elif abs(board[c]-row) == abs(c-column):
 return False
 return True
def Queens(board, column):
 #do stuff
 for row in range(8):
 if place(board, row, column):
 board[column]=row
 if column==7:
 return True
 else:
 if(Queens(board, column+1)):
 return True
 else:
 #backtracking
 board[column]= -1 
 if row==8:
 return False
def HailHydra(board):
 print("------------------****------------------")
 data = [['_']*8 for _ in xrange(8)]
 for i in xrange(8):
 data[i][board[i]]='Q'
 for i in xrange(8):
 print data[i]
def main():
 position = 2
 board = [-1]*8
 if(position>=0 and position<8):
 board[0]=position
 if(Queens(board, 1)):
 HailHydra(board)
 return True
 else:
 print "Cant have board with initial queen at:", position
 return False
 else:
 print "Invalid input"
 return False
main()

This code results in output

------------------****------------------
['_', '_', 'Q', '_', '_', '_', '_', '_']
['Q', '_', '_', '_', '_', '_', '_', '_']
['_', '_', '_', '_', '_', '_', 'Q', '_']
['_', '_', '_', '_', 'Q', '_', '_', '_']
['_', '_', '_', '_', '_', '_', '_', 'Q']
['_', 'Q', '_', '_', '_', '_', '_', '_']
['_', '_', '_', 'Q', '_', '_', '_', '_']
['_', '_', '_', '_', '_', 'Q', '_', '_']

In the above code if we exchange

data = [['_']*8 for _ in xrange(8)]

this line in the main functions with

data = [['_']*8]*8

The output changes to

------------------****------------------
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']
['Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q', 'Q']

According to my understanding of python the two different list definitions should result in same output, but it appears that i missing some details which are resulting the the above mentioned situations.

My question is

What exactly is the difference between the list definitions of the following 2 types

1. [['_']*8 for _ in xrange(8)]

and

2. data = [['_']*8]*8

which led to generations to these 2 different output

asked Jul 3, 2017 at 17:23
0

3 Answers 3

2

By typing [['_']*8]*8 you are creating a list of the same list instance:

ls = [['_']*8]*8
ls[5][5] = 'Q'
print ls

Here you can see, 'Q' is placed 8 times.

answered Jul 3, 2017 at 17:29

Comments

2

The first constructs a list of 8 separate lists. The second constructs a list containing the same list 8 times.

answered Jul 3, 2017 at 17:29

Comments

1

[['_']*8 for _ in xrange(8)] and data = [['_']*8]*8 produces actually exactly same output as long as they are not touched

>>> a = [['_']*8 for _ in xrange(8)]
>>> b = [['_']*8]*8
>>> a == b
True

But as @hurturk and @Blotosmetek rightly said, b is actually a copy of same list over and over again. Any change in one list in b, will have same impact on other lists in b.

Whereas a, is list of independent lists.

>>> a[1][1]='Q'
>>> b[1][1]='Q'
>>> a == b
False
>>> 
answered Jul 3, 2017 at 17:37

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.