有关改进此功能的提示?

时间:2012-09-03 09:11:03

标签: python math polygon

这可能是一个非常绿色的问题,但我希望你理解 - 刚开始使用python并尝试改进。无论如何,写了一个小函数来做“Shoelace方法”,在笛卡尔平面上找到多边形的区域(参见this进行复习)。

我想知道如何改进我的方法,所以我可以尝试新的方式来做同样的旧事。

    def shoelace(list):
        r_p     = 0         # Positive Values
        r_n     = 0         # Negative Values

        x, y    = [i[0] for i in list], [i[1] for i in list]
        x.append(x[0]), y.append(y[0])

        print(x, y)

        for i in range(len(x)):
            if (i+1) < len(x):
                r_p += (x[i] * y[i+1])
                r_n += (x[i+1] * y[i])
            else:
                break

        return ((abs(r_p - r_n))/2)

2 个答案:

答案 0 :(得分:2)

  • 不要使用需要注释的短变量名;使用表示功能的名称。

  • list是内置列表类型的名称,所以虽然Python会让你替换这个名字,但这在风格上是个坏主意。

  • ,不应该用于分隔应该是什么语句。您可以使用;,但通常更好的方法是将内容放在不同的行上。在您的情况下,它恰好起作用,因为您使用.append作为副作用,但基本上您正在做的是构建2元组(None, None)(来自.append的返回值)扔掉它。

  • 尽可能使用内置函数进行标准列表转换。例如,请参阅zip的文档。除非你真的不需要进行这种转变;你想要考虑成对的相邻点,所以这样做 - 并在循环内拆开它们的坐标。

  • 但是,您可以使用zip将点列表转换为相邻点对的列表:)这样可以让您编写更清晰的循环。这个想法很简单:首先,我们列出相对于原件的所有“下一个”点,然后我们zip将两个点列表放在一起。

  • return不是一个函数,所以你return的东西不需要包围括号。

  • 不是计算单独的正值和负值,而是对单个值执行带符号算术。


def shoelace(points):
    signed_double_area = 0

    next_points = points[1:] + points[:1]

    for begin, end in zip(points, next_points):
        begin_x, begin_y = begin
        end_x, end_y = end
        signed_double_area += begin_x * end_y
        signed_double_area -= end_x * begin_y

    return abs(signed_double_area) / 2

答案 1 :(得分:0)

从功能上讲,你的程序非常好。一个小问题是将range(len(x))替换为xrange(len(x))。它使程序稍微更有效率。通常,只有在您确实需要其创建的完整值列表的情况下,才应使用range。如果您只需要遍历这些值,请使用xrange

此外,您不需要return语句中的括号,也不需要r_p +=r_n +=语句中的括号。

关于样式,在Python中,变量赋值不应该像你那样完成,而是在=符号的每一边都有一个空格:

r_p = 0
r_n = 0