有没有更整洁的方法来建立此列表? Python 3

时间:2020-01-07 22:00:46

标签: python

我想知道是否有更巧妙的方法来编写代码的第3部分? 我正在建立一个井字游戏来进行分配,这是检查是否有3个X或O的行的功能。因此,我将代表3x3游戏板的“面板”列表分为三个列表,分别表示行,列和“角到角”线。

def check_forwin(board,split_list):

    #part 1 splice a single list into 3 lists
    check_list1 = [tuple(board[i:j]) for i, j in zip([1]+ split_list, split_list)]
    #part 2"invert" the list, as in choosing columns 
    check_list2 = list(zip(check_list1[0],check_list1[1],check_list1[2]))

    #part 3 make 2 lists from "corner to corner"
    check_list3 = [[],[]]

    check_list3[0] = tuple([check_list1[0][0],check_list1[1][1],check_list1[2][2]])
    check_list3[1] = tuple([check_list1[0][2],check_list1[1][1],check_list1[2][0]])

    return 

board = ["#","a","b","c","d","e","f","g","h","i"]
split_list1 = [4, 7, 10]

check_forwin(board,split_list1)

[('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i')]
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]
[('a', 'e', 'i'), ('c', 'e', 'g')]

3 个答案:

答案 0 :(得分:1)

有趣的问题,尽管“整洁”是一个非常主观的概念……您对此有何看法?

stream.reduce(accumulatorFunction).orElse(defaultValue)

答案 1 :(得分:1)

使用列表理解会使它更整洁,但是,正如卡尔玛所说,“整洁”是非常主观的。

def check_forwin(board,split_list):

    #part 1 splice a single list into 3 lists
    check_list1 = [tuple(board[i:j]) for i, j in zip([1]+ split_list, split_list)]

    #part 2"invert" the list, as in choosing columns 
    check_list2 = list(zip(check_list1[0],check_list1[1],check_list1[2]))

    #part 3 make 2 lists from "corner to corner"
    check_list3 = [[],[]]

    # Number of element in row or column
    n = len(check_list1)
    check_list3[0] = tuple([check_list1[i][i] for i in range(n)])
    check_list3[1] = tuple([check_list1[i][n-i-1] for i in range(n)])

    return 

答案 2 :(得分:0)

如果只需要将一个列表转换为列表列表,则可以使用以下两种方法之一。但是,我读错了说明,并认为您希望实施整个游戏检查器。那就是我早些时候发布的答案。虚线下方是该实现方式。我保留了它,但是如果您不感兴趣,则可以忽略下面的行。======“

使用基本python的方法1

import math
def Convert_Into_SquareBoard_UsingBasePython(List):
    List = List[1:]
    return [ [List[i*int(math.sqrt(len(List)))+j] for j in range(3)] for i in range(0,int(math.sqrt(len(List))),1)]

这给出了以下输出。

[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]

使用Numpy的方法2

def Convert_Into_SquareBoard_UsingNumpy(List):
    return np.array(List[1:]).reshape(int(np.sqrt(len(List[1:]))),int(np.sqrt(len(List[1:])))).tolist()

这将提供与上面相同的输出

[['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]

============================================ ========================

好答案已经发布。但是,如果允许使用numpy,则可以用另一种方式来实现。基本上,您将列表列表转换为numpy数组,然后检查“行”,“列”和“对角线”获胜。就优雅而言,我不确定。尽管如此,我仍在发布它,为解决方案添加另一种方法。

import numpy as np

def Check_Win(a):
    a = np.array(a)

    ##Get both diagonals
    Diag_Array = np.array([a.diagonal(),np.flip(a,1).diagonal()])

    ##Check 1 for row win
    if np.any(np.apply_along_axis(lambda x: len(set(x))==1, 1, a)):
        return True
    ##Check 2 for column win
    elif np.any(np.apply_along_axis(lambda x: len(set(x))==1, 0, a)):
        return True
    ##Check 3 along diagonals
    elif np.any(np.apply_along_axis(lambda x: len(set(x))==1, 1, Diag_Array)):
        return True
    return False

a_No_Win = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'h', 'i')]

a_Row_Win = [('a', 'b', 'c'), ('d', 'e', 'f'), ('g', 'g', 'g')]

a_Column_Win = [('h', 'b', 'c'), ('h', 'e', 'f'), ('h', 'h', 'i')]

a_Diag_1_Win = [('a', 'b', 'c'), ('d', 'a', 'f'), ('g', 'h', 'a')]

a_Diag_2_Win = [('a', 'b', 'h'), ('d', 'h', 'f'), ('h', 'h', 'i')]

print(Check_Win(a_No_Win))
print(Check_Win(a_Row_Win))
print(Check_Win(a_Column_Win))
print(Check_Win(a_Diag_1_Win))
print(Check_Win(a_Diag_2_Win))

这提供了预期的输出。

False
True
True
True
True

在意识到输入是平面列表而不是列表列表,并且第一个元素是要注意的字符后,在下面添加了行

要使上述方法起作用,您必须首先获取列表列表。此外,它不会查找特定字符。只要任何角色以连续的方式出现,它就会注册一个胜利。我想你不是要找那个。

我认为您只有一个列表,并且列表的第一个元素是您要寻找获胜者的角色。您忽略的所有其他字符。下面是上述功能的修改版本。稍有更改,以“也许”满足您的需求。

import numpy as np

def Check_Win(a):
    CheckSymbol = a[0]
    a = np.array(a[1:]).reshape(int(np.sqrt(len(a[1:]))),int(np.sqrt(len(a[1:]))))

    ##Get both diagonals
    Diag_Array = np.array([a.diagonal(),np.flip(a,1).diagonal()])

    ##Check 1 for row win
    if np.any(np.apply_along_axis(lambda x: list(x).count(CheckSymbol)==int(np.sqrt(len(a[1:]))), 1, a)):
        return True
    ##Check 2 for column win
    elif np.any(np.apply_along_axis(lambda x: list(x).count(CheckSymbol)==int(np.sqrt(len(a[1:]))), 0, a)):
        return True
    ##Check 3 along diagonals
    elif np.any(np.apply_along_axis(lambda x: list(x).count(CheckSymbol)==int(np.sqrt(len(a[1:]))), 1, Diag_Array)):
        return True
    return False

a_No_Win = ["#","a","b","c","d","e","f","g","h","i"]

a_Row_Win = ["#","a","b","c","d","e","f","#","#","#"]

a_Column_Win = ["#","#","b","c","#","e","f","#","h","i"]

a_Diag_1_Win = ["#","#","b","c","d","#","f","g","h","#"]

a_Diag_2_Win = ["#","a","b","#","d","#","f","#","h","i"]

print(Check_Win(a_No_Win))
print(Check_Win(a_Row_Win))
print(Check_Win(a_Column_Win))
print(Check_Win(a_Diag_1_Win))
print(Check_Win(a_Diag_2_Win))

修改后的输出如下所示,并且符合预期。

False
True
True
True
True

请告诉我这是否有帮助。