【问题标题】:How can I make my code simpler and still get the same output?我怎样才能使我的代码更简单并且仍然获得相同的输出?
【发布时间】:2021-11-07 01:44:04
【问题描述】:

所以我不得不编写代码来查找网格中的所有对角线字符串mystery

mystery = [["r","a","w","b","i","t"],
           ["x","a","y","z","c","h"],
           ["p","q","b","e","i","e"],
           ["t","r","s","b","o","g"],
           ["u","w","x","v","i","t"],
           ["n","m","r","w","o","t"]]

在一些专家的帮助下,这就是我目前所拥有的,因为我是新手。帮助我的专家是https://stackoverflow.com/users/5237560/alain-t

def diagsDownRight(M):
    diags,pad = [],[]
    while any(M):
        edge = [*next(zip(*reversed(M))),*M[0][1:]]
        M    = [r[1:] for r in M[1:]]
        diags.append(pad+edge+pad)
        pad.append("")
    return [*map("".join,zip(*diags))]

虽然这确实有效,但我自己觉得很难掌握,我不想只写下我不理解的代码。那么,任何人都可以帮助使代码尽可能基本吗?

当我的意思是尽可能基本的时候,我的意思是把自己想象成一个刚刚学习了几个月的编码的人,请尽量简化我的代码。

【问题讨论】:

  • 对角线是否只是从左上到右下,从右上到左下的两条 6 长对角线?还是棋盘内的每一条对角线?
  • 这不是简单的代码,也不是简单的算法。承认吧,你的专家为你写的,不是“在……的帮助下”。初读时我觉得很难掌握,而且我已经使用 python 工作了好几年。如果他们能评论他们的代码就好了。
  • 另外,只是一个注释,但上面包含的解决方案似乎来自here;我承认代码很混乱,tbh。
  • 老实说,但如果我看到它在生产代码中使用,也许是在我正在工作的团队中,我可能会尽快逃跑。所以我至少在这点上绝对同意 OP。

标签: python list tuples


【解决方案1】:

我能想到的最简单的方法:填充行,使对角线变成列。代码:

def diagsDownRight(M): 
    n = len(M)
    m = [[''] * (n-i-1) + row + [''] * i for i, row in enumerate(M)]  # pad rows 
    return [''.join(col) for col in zip(*m)] 

结果是一样的,IMO的方法更直观

【讨论】:

  • 感谢您抽出时间来帮助我。顺便说一句,如果我们想从左侧向下做,我们使用 m = [[''] * (n+i+1) 还是 smth?
  • @Bruffff 是的,同样的事情只是 n-i-1i 切换:m = [['']*i + row + ['']*(n-i-1) for i, row in enumerate(M)]
  • 还有一个简单的问题,如果我们想像倒着一样打印怎么办。就像从你提供的代码中一样,这些值是从上到下打印的,比如 n、um、twr 等等。但是如果我想从下到上打印出来,比如 n、mu、rwt 等等,我可以做return return (reversed[''.join(col) for col in zip(*m)] ) 还是有其他解决方案?
  • @Bruffff 在最后一行,反向列:''.join(reversed(col))
【解决方案2】:

考虑一个方阵

[
 [ 1, 2, 3 ],
 [ 4, 5, 6 ],
 [ 7, 8, 9 ]
]

对角线的索引如下

d1 = [[0,0],[1,1],[2,2]]
d2 = [[0,1],[1,2]]
d3 = [[1,0],[2,1]]
d4 = [[2,0]]
d5 = [[0,2]]

要获得中间对角线,您可以简单地从索引开始

for i in range(3):
    index = [i,i]

对于下一个对角线,我们只是简单地做同样的事情......但将 x 偏移 1,直到我们超出界限

for i in range(3):
   if i + 1 > 2:
      break
   index = [i, i+1]

对于下一个对角线,它是相同的......除了我们在另一个轴上做它

for i in range(3):
   if i + 1 > 2:
      break
   index = [i + 1, i]

对于最右上角(在这种情况下...)它是相同的,但我们添加了 2

 for i in range(3):
   if i + 2 > 2:
      break
   index = [i, i+2]

最底部相同,但使用其他索引

 for i in range(3):
   if i + 2 > 2:
      break
   index = [i + 2, i]

我会留给您将其推断为可行的解决方案

【讨论】:

    【解决方案3】:

    这是一个更简单的版本:

    def diagsDownRight(M):
        rows = len(M)      # number of rows
        cols = len(M[0])   # number of columns
        result   = []      # result will be a list of strings
        leftSide = [(r,0) for r in range(rows)]   # first column
        topSide  = [(0,c) for c in range(1,cols)] # first row
        for r,c in leftSide[::-1] + topSide:      # all start positions
            s = "" # string on the diagonal
            while r < rows and c < cols:
                s += M[r][c]  # accumulate characters
                r += 1        # move down
                c += 1        # and to the right
            result.append(s)  # add diagonal string to result
        return result
    
    print(diagsDownRight(mystery))
    ['n', 'um', 'twr', 'prxw', 'xqsvo', 
     'rabbit', 'ayeot', 'wzig', 'bce', 'ih', 't']
    

    它的工作方式是从左上角坐标开始,向右下一个位置累积字符,直到走出矩阵。

    不过,我建议您采用 Marat 的解决方案。它简单而优雅。如果你打印m 矩阵,我敢肯定,你会明白发生了什么

    【讨论】:

    • 好点,我会这样做的
    猜你喜欢
    • 2017-11-17
    • 1970-01-01
    • 2022-12-12
    • 2023-02-01
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    相关资源
    最近更新 更多