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

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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

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
>>> 

Comments

Your Answer

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.