0

这可能是一个非常绿色的问题,但我希望你能理解——刚刚开始使用 python 并试图改进。无论如何,写了一个小函数来执行在笛卡尔平面中找到多边形区域的“鞋带方法”(请参阅​​this for a refresh)。

我想知道如何改进我的方法,这样我就可以尝试花哨的新方法来做同样的旧事情。

    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)
4

2 回答 2

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
于 2012-09-03T11:20:11.337 回答
0

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

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

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

r_p = 0
r_n = 0
于 2012-09-03T09:13:54.433 回答