Pythonic方法检查嵌套列表中的对角线

时间:2017-09-22 00:32:36

标签: python n-queens

我有一个0和1的嵌套列表,例如:

L = [[1, 0, 1],
     [0, 0, 0],
     [0, 0, 1]]

我想检查一下是否有任何对角线。嵌套列表可以有任何大小,只要子列表的长度等于整个列表的长度(它是一个正方形)。因此,如果我在上面的列表中运行它,它将返回False,因为两个是对角线。

我目前的代码是:

for num, i in enumerate(List):
    for count, m in enumerate(i):
        key1 = True
        key2 = True
        key3 = True
        key4 = True
        num1 = num
        num2 = num
        num3 = num
        num4 = num
        count1 = count
        count2 = count
        count3 = count
        count4 = count
        if m == 1:
            while key1 or key2 or key3 or key4:
            #print(key1, key2, key3, key4)
                try:
                    if List[num1 + 1][count1 + 1] == 1:
                        print(List[num1 + 1][count1 + 1])
                        return False
                    num1 += 1
                    count1 += 1
                except IndexError:
                    key1 = False
                try:
                    if List[num2 - 1][count2 + 1] == 1:
                        if num2 > 0:
                            print(List[num2 - 1][count2 + 1])
                            return False
                    num2 -= 1
                    count2 += 1
                except IndexError:
                        key2 = False
                try:
                    if List[num3 + 1][count3 - 1] == 1:
                        if count3 > 0:
                            print(List[num3 + 1][count3 - 1])
                            print(num3 + 1, count3 - 1)
                            return False
                    num3 += 1
                    count3 -= 1
                except IndexError:
                    key3 = False
                try:
                    if List[num4 - 1][count4 - 1] == 1:
                        if count4 > 0 and num4 > 0:
                            print(List[num4 - 1][count4 - 1])
                            return False
                    num4 -= 1
                    count4 -=1
                except IndexError:
                    key4 = False
return True

代码扫描列表1秒,当找到一个时,它会查看其四个角并搜索它们。它继续沿角落方向搜索,一次移动一个网格。如果找到另一个1,则返回false。一旦搜索了所有可能的对角线网格(直到返回索引错误),代码就会移动到找到的下一个1。一旦搜索到每一个1并且没有找到任何对角线,代码将返回true。

感觉笨重而且效率低下,但我不确定如何压缩它。有没有更短的方法来做到这一点?

4 个答案:

答案 0 :(得分:3)

您可以像这样访问对角线:

L = [[1, 0, 1],
 [0, 0, 0],
 [0, 0, 1]]

diag1 = [L[i][i] for i in range(len(L))]
diag2 = [L[i][len(L[0])-i-1] for i in range(len(L))]
if diag1 == diag2:
   pass #do something here

答案 1 :(得分:2)

您可以从考虑命名对角线的方法开始。例如,在3x3矩阵中,索引(x,y)如下所示:

(0,0) (1,0) (2,0)
(0,1) (1,1) (2,1)
(0,2) (1,2) (2,2)

如果我们遵循对角线,他们的指数有一个简单的模式。左下角到右上角的对角线是:

Diag #1 (0,0)
Diag #2 (0,1) (1,0)
Diag #3 (0,2) (1,1) (2,0)
Diag #4 (1,2) (2,1)
Diag #5 (2,2)

从左上角到右下角,他们是:

#1 (0,2)
#2 (0,1) (1,2)
#3 (0,0) (1,1) (2,2)
#4 (1,0) (2,1)
#5 (2,0)

请注意,在左下角到右上角的情况下,同一对角线上的每个单元格(x,y)都具有相同的x + y值。在另一种情况下,同一对角线上的每个单元具有相同的x-y值。显然,对于任何大小的矩阵都是如此。我们可以使用x + y和x-y来命名各个对角线。当我们逐步完成矩阵时,每次遇到" 1"我们可以立即计算出那里相交的两条对角线的名称。

这表明了一种有效的算法,用于判断任何两个" 1"是否在同一对角线上。在Python中,我们可以使用两组来跟踪"被占用的"对角线。如果我们遇到" 1"在已占用的对角线上,我们返回True,否则为false。如果我们访问所有元素,我们可以按任意顺序逐步完成矩阵。

def has_diagonal_ones(a):
    # a is a 2-dimensional square array of 0's and 1's
    lower_left_upper_right = set()
    upper_left_lower_right = set()
    for x in range(len(a)):
         for y in range(len(a)):
             if a[x][y] == 0:
                 continue
             i_lower_to_upper = x + y
             i_upper_to_lower = x - y
             if i_lower_to_upper in lower_left_upper_right:
                 return True
             if i_upper_to_lower in upper_left_lower_right:
                 return True
             lower_left_upper_right.add(i_lower_to_upper)
             upper_left_lower_right.add(i_upper_to_lower) 
    return False

L = [[1, 0, 1],
 [0, 0, 0],
 [0, 0, 1]]
print(has_diagonal_ones(L))

>>> True

答案 2 :(得分:1)

你可以使用numpy来解决这个问题。



import numpy as np
def diagonal(arr):
    d = np.diag(a)

    set_len = len(set(d))
    d_len = len(d)
    if set_len < d_len:
        return False
    else:
        return True

a = np.array([[1, 0, 1], [0, 0, 0], [0, 0, 1]])
print(diagonal(a))
&#13;
&#13;
&#13;

答案 3 :(得分:0)

我有一个lib。结帐诊断和adiag功能! https://github.com/dhilst/funcyou/blob/master/funcyou/indexers.py