TicTacToe with Python def tictactoe():
    Board = [1,2,3,4,5,6,7,8,9]
    w = True
    PlayerX = []
    PlayerO = []
    while len(PlayerO) &lt; 9:
        while True:
            z = int(input("Player X: Select a place (1-9)\n"))
            if z in Board:
                Board[z-1] = []
                PlayerX.append(z)
                break
            else:
                print("Place not available! Choose another X")
        while True:
            y = int(input("Player O: Select a place (1-9)\n"))
            if y in Board:
                Board[y-1] = []
                PlayerO.append(y)
                break
            else:
                print("Place not available! Choose another O")
        if len(PlayerX) &gt; 2:
            if set([1,2,3]).issubset(set(PlayerX)) or set([4,5,6]).issubset(set(PlayerX)) or set([7,8,9]).issubset(set(PlayerX)) or set([1,4,7]).issubset(set(PlayerX)) or set([2,5,8]).issubset(set(PlayerX)) or set([3,6,9]).issubset(set(PlayerX)) or set([1,5,9]).issubset(set(PlayerX)) or set([3,5,7]).issubset(set(PlayerX)):
                print("Player X won!")
                w = False
                break
            elif set([1,2,3]).issubset(set(PlayerO)) or set([4,5,6]).issubset(set(PlayerO)) or set([7,8,9]).issubset(set(PlayerO)) or set([1,4,7]).issubset(set(PlayerO)) or set([2,5,8]).issubset(set(PlayerO)) or set([3,6,9]).issubset(set(PlayerO)) or set([1,5,9]).issubset(set(PlayerO)) or set([3,5,7]).issubset(set(PlayerO)):
                print("Player O won!")
                w = False
                break
    if w is True:
        print("Tie")
    if input("Play Again (y/n)?\n") == "y":
        tictactoe()
tictactoe()


I'm trying to make this code as efficient as possible. I'm new to Python and kinda limited with the knowledge I have. How can I simplify the code and especially the line shown below?



if set([1,2,3]).issubset(set(PlayerX)) or set([4,5,6]).issubset(set(PlayerX)) or set([7,8,9]).issubset(set(PlayerX)) or set([1,4,7]).issubset(set(PlayerX)) or set([2,5,8]).issubset(set(PlayerX)) or set([3,6,9]).issubset(set(PlayerX)) or set([1,5,9]).issubset(set(PlayerX)) or set([3,5,7]).issubset(set(PlayerX)):
I guess from efficiency point of view this is fine, even that last line. Efficiency points:


You create player variable as list and then keep converting to set over and over again, why not have it as set from beginning?


From readability and maintenance point of view, you are having lots of duplicities.


Player moves are exactly same except for message and variable, you can extract that to function.
Same goes for checking if a player won.
I don't like variable w. Why not make variable winner instead and save name of winner into it? Related to extracting if player won to separate function.


And for your last line - you can put all possible winning combinations into array or tupple and then check that in cycle (you get the idea):

winning_combinations = [
[1, 2, 3],
[4, 5, 6],
...
]