【问题标题】:Python: Possible to exchange math operators so as to avoid code duplication?Python:可以交换数学运算符以避免代码重复吗?
【发布时间】:2020-01-03 18:09:22
【问题描述】:

我有这个功能(见下文),它看起来像是重复了四次。四个代码 sn-ps 非常相似,只是在一些数学运算符上有所不同。是否可以使此代码更短?我找不到方法,但我希望能够只调用一个函数(在函数中),在代码 sn-ps 中交换“-”、“+”和“”符号,以便我不必重复它们?

代码

def diag_grannar(storlek,troll_position): #funktion som kollar efter diagonala grannar
    ny_rad = troll_position[0]
    ny_kol = troll_position[1]
    diag_grannar = []

    # while-loopen letar efter diagonala grannar snett vänster ovanifrån troll_position
    while True:
        ny_rad -= 1
        ny_kol -= 1
        if ny_rad >= 1 and ny_kol >= 1:
            diag_grannar.append([ny_rad,ny_kol])
        else:
            ny_rad = troll_position[0]
            ny_kol = troll_position[1]
            break

    # while-loopen letar efter diagonala grannar snett vänster nedanifrån troll_position
    while True:
        ny_rad += 1
        ny_kol -= 1
        if ny_rad <= storlek and ny_kol >= 1:
            diag_grannar.append([ny_rad,ny_kol])
        else:
            ny_rad = troll_position[0]
            ny_kol = troll_position[1]
            break

    # while-loopen letar efter diagonala grannar snett höger nedanifrån troll_position
    while True:
        ny_rad += 1
        ny_kol += 1
        if ny_rad <= storlek and ny_kol <= storlek:
            diag_grannar.append([ny_rad,ny_kol])
        else:
            ny_rad = troll_position[0]
            ny_kol = troll_position[1]
            break

    # while-loopen letar efter diagonala grannar snett höger ovanifrån troll_position
    while True:
        ny_rad -= 1
        ny_kol += 1
        if ny_rad >= 1 and ny_kol <= storlek:
            diag_grannar.append([ny_rad,ny_kol])
        else:
            ny_rad = troll_position[0]
            ny_kol = troll_position[1]
            break

    return diag_grannar

为了清楚起见,我指的代码 sn-ps 是这些:

while True:
    ny_rad -= 1
    ny_kol += 1
    if ny_rad >= 1 and ny_kol <= storlek:
        diag_grannar.append([ny_rad,ny_kol])
    else:
        ny_rad = troll_position[0]
        ny_kol = troll_position[1]
        break

最好的问候;

【问题讨论】:

    标签: python function code-duplication


    【解决方案1】:

    让我们从完全摆脱循环开始:

    def diag_grannar(storlek,troll_position):
        ny_rad = troll_position[0]
        ny_kol = troll_position[1]
        diag_grannar = []
    
        diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol-1, 0, -1)))
        diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol-1, 0, -1)))
        diag_grannar.extend([x,y] for x, y in zip(range(ny_rad+1, storlek+1), range(ny_kol+1, storlek+1)))
        diag_grannar.extend([x,y] for x, y in zip(range(ny_rad-1, 0, -1), range(ny_kol+1, storlek+1)))
    
        return diag_grannar
    

    现在我们可以在必要时反转范围。 range(x-1, 0, -1)reversed(range(1, x)) 相同。

    def diag_grannar(storlek,troll_position):
        ny_rad = troll_position[0]
        ny_kol = troll_position[1]
        diag_grannar = []
    
        xs = range(1, ny_rad + 1)
        ys = range(1, ny_kol + 1)
    
        diag_grannar.extend(list(t) for t in zip(reversed(xs), reversed(ys))
        diag_grannar.extend(list(t) for t in zip(xs, reversed(ys))
        diag_grannar.extend(list(t) for t in zip(xs, ys))
        diag_grannar.extend(list(t) for t in zip(reversed(xs), ys))
        return diag_grannar
    

    【讨论】:

      【解决方案2】:

      如果将重复代码放在函数中,则可以将内置operator 模块中的函数作为参数传入,并使用这些函数。

      【讨论】:

        【解决方案3】:

        我们可以遍历同一事物的各种参数化...需要注意的是,我们总是可以使用加法而不是交换数学运算符,只需添加 1 或 -1(比交换匹配运算符更容易)

        def diag_grannar1(storlek,troll_position): #funktion som kollar efter diagonala grannar
            ny_rad = troll_position[0]
            ny_kol = troll_position[1]
            diag_grannar = []
            def diag_compare(v1, leq):
                if leq:
                    return v1 <= storlek
                else:
                    return v1 >= 1
            params = [((-1, -1, False, False)),
                      ((1, -1, True, False)),
                      ((1, 1, True, True)), 
                      ((-1, 1, False, True))]
        
            for v1, v2, leq1, leq2 in params:
                while True:
                    ny_rad += v1
                    ny_kol += v2
                    if diag_compare(ny_rad, leq1) and diag_compare(ny_kol, leq2):
                        diag_grannar.append([ny_rad,ny_kol])
                    else:
                        ny_rad = troll_position[0]
                        ny_kol = troll_position[1]
                        break
        
            return diag_grannar
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-28
          • 1970-01-01
          相关资源
          最近更新 更多