在列表python 3中查找矩阵中的模式

时间:2017-05-17 00:27:37

标签: python list python-3.x function

我有一个由列表组成的列表,用于创建一个矩阵,主要用零和其他一些数字填充

a = [[0,0,0,1,0,0,0,0],
     [3,0,0,2,1,0,0,0],
     [3,0,0,0,0,1,0,0],
     [3,5,0,4,0,0,0,0]]

我怎样才能创建一个接受该变量的函数,并找出是否在对角线中重复了3次?

例如,由于1,它返回True。 我试图实现这样的函数:

def find_diagonal(matriz):
    for x in range(len(matrix)):
        for for a in range(len(x)):
            if matriz[x][a] != 0:
                encontrar = matriz[x][a]
                if matriz[x+1][a-1] == encontrar:
                    if matriz[x+2][a-2] == encontrar:
                        return True

并在if matriz[x][a] != 0之后重复其他对角线的条件(这个条件寻找指向西南方向的条件)。

但除了不处理每个例子(有时它工作一次,并停止使用相同的例子),并且在边缘总是引发索引错误,因为列表检查顶部的行。

2 个答案:

答案 0 :(得分:1)

正如@ShadowRanger所指出的那样,使用扁平列表可能更容易,并且使用切片与rowlen的步骤+/- 1(这会为您提供对角线的项目):< / p>

def has_diagonals(listoflist, n=3):
    rowlen = len(listoflist[0])
    numrows = len(listoflist)
    l = [i for row in listoflist for i in row]
    for rownr in range(numrows + 1 - n):
        # Diagonals to the lower right
        for start in range(rowlen + 1 - n):
            lr_diag = l[start+rownr*rowlen::rowlen+1][:n]
            print(lr_diag)
            first = lr_diag[0]
            if first == 0:  # don't check for zero-diagonals
                continue
            if all(item == first for item in lr_diag):  # are all items equal
                print('match', lr_diag)

        # Diagonals to the lower left   
        for start in range(n - 1, rowlen):
            rl_diag = l[start+rownr*rowlen::rowlen-1][:n]
            print(rl_diag)
            first = rl_diag[0]
            if first == 0:  # don't check for zero-diagonals
                continue
            if all(item == first for item in rl_diag):  # are all items equal
                print('match', rl_diag)

我包含了一些print - 用来形象化内部工作的调用,我认为这些可能会帮助您了解正在发生的事情。带print的{​​{1}}应替换为'match'或您希望函数返回的任何内容。

可以提高效率,但它应该是正确的(至少对于你的return True矩阵而言)

答案 1 :(得分:1)

这个怎么样:

def check_diag(a, y, x):
  """Take a[y][x] and check if it starts a diagonal"""
  result = False

  # We search downwards, there should be at least 2 more rows
  if y > len(a)-2:
    return False

  if x < len(a[y])-2:
      # Searching SE direction if possible
      result |= (a[y][x] == a[y+1][x+1] == a[y+2][x+2])
  if x > 1:
      # Searching SW direction if possible
      result |= (a[y][x] == a[y+1][x-1] == a[y+2][x-2])

  return result

def has_diag(a):
  # Take all non-zero elements and check if they meet the diag condition
  return any([check_diag(a,y,x)
                for y in range(len(a))
                for x in range(len(a[y]))
                if a[y][x]])

这也会找到更长的对角线,不确定你是否想要它。

编辑:更多&#34;野蛮&#34;具有较少索引魔法的版本:

def check_diag2(a, y, x):
  """Take a[y][x] and check if it starts a diagonal"""
  try:
    if (a[y][x] == a[y+1][x+1] == a[y+2][x+2]):
      return True
  except IndexError:
    pass

  try:
    if (a[y][x] == a[y+1][x-1] == a[y+2][x-2]):
      return True
  except IndexError:
    pass

  return False