I am creating a game of checkers using the but am struggling to find a good internal representation for the game. My initial thoughts were to store the game board in a 2d list, with 0=empty, 1=always empty, 2=team 1, 3=team 2. My second idea was to create a Piece class and append piece objects to an list, passing the x, y co-ordinates of each piece as I do this. Would anyone be able to suggest the best way to go about this. I later want to implement the min max algorithm.
Both of your proposals can work.
A 2D list for the board gives you the advantage that you can check whether a space contains a piece just by indexing with the coordinates of that space.
But when you want to iterate over all of the pieces for a player (say, to check all their available moves, or evaluate the victory condition/heuristic), you have to iterate over the whole board. (Not dire, when it's only 64 iterations)
A list of piece objects gives you the advantage that you can easily iterate over all of the pieces, particularly if you partition them by their owning player.
But when you want to check whether a particular tile contains a piece, you have to iterate over the whole list checking for a piece with matching coordinates. (Not dire, when it's only 24 iterations at max)
You might notice that these pros and cons are exactly complementary: one representation excels where the other representation is weakest. So that gives you a third option: use both. That way you can use the most convenient structure for each task. You just need a little book-keeping to keep the two structures in-sync, so they never disagree about where the pieces are. It might seem redundant, but we're talking a matter of bytes here - this whole thing will fit in your CPU cache, so there's no need to be stingy with data structure memory here if it makes your other code simpler.