Home > Net >  How to prevent a for loop from adding the same element in Python?
How to prevent a for loop from adding the same element in Python?

Time:05-18

I have a variable, representing a chessboard filled with random chess pieces. The variable consists of a list of 8 lists,each containing 8 positions filled with either " " (empty position) or a specific chess piece (e.g. "♞"):

chessboard = [
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ','♞','♞',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ','♔',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' '],
[' ',' ',' ',' ',' ',' ',' ',' ']
]

I would like to collect the information of each individual piece in a list:

pieces = []
for row in chessboard:
        for piece in row:
            if piece != " ":
                pieces.append((piece, row.index(piece), chessboard.index(row)))

The above for loop ALMOST works. It has one problem. If there are multiple identical pieces in the same row, it adds the coordinates of the first iterated piece:

[('♞', 5, 2), ('♞', 5, 2), ('♔', 2, 5)]

The second knight should be in position 5,3. Can anybody suggest a workaround?

CodePudding user response:

Loop over enumerate(row) and enumerate(row), and if the cell isn't ' ' then add the indices to your list. This is also more efficient, as your solution loops across each row multiple times - once to get across the row, and once each time it wants to find the index of a piece.

CodePudding user response:

enumerate the rows and columns.

pieces = []
for i, row in enumerate(chessboard):
        for j, piece in enumerate(row):
            if piece != " ":
                pieces.append((piece, i, j))

CodePudding user response:

Using a list comprehension:

out = [(item, j, i) for i,row in enumerate(chessboard)
                    for j,item in enumerate(row) if item != ' ']

or numpy.where:

import numpy as np

a = np.array(chessboard)
i,j = np.where(a!=' ')
out = list(zip(a[i,j], j, i))

output:

[('♞', 5, 2), ('♞', 6, 2), ('♔', 2, 5)]

CodePudding user response:

There are already some good answers to this question, but I find that numpy may be a good choice for this question:

>>> import numpy as np
>>> board = np.array(chessboard)
>>> board
array([[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', ' ', '♞', '♞', ' ', ' '],
       [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', '♔', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '],
       [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']], dtype='<U1')
>>> i, j = (board != ' ').nonzero()
>>> list(zip(board[i, j], j, i))
[('♞', 4, 2), ('♞', 5, 2), ('♔', 2, 5)]
  • Related