Python到c#减少了对函数的理解

时间:2011-11-05 08:36:28

标签: c# python reduce

我正在努力理解下面在python中写的'reduce'调用。

我在这里和其他地方找到了几个来源,说明了函数的功能,并且C#中的列表有一个等效的“聚合”,但是我无法理解下面的调用实际上是什么 - 期望 - 。 ..可能是因为我无法确定'_keep_left'会返回什么?

所以:

1-有人可以帮我告诉'_keep_left'返回什么?

2- , [])在减少呼叫中的含义是什么?

非常感谢。

TURN_LEFT, TURN_RIGHT, TURN_NONE = (1, -1, 0)

def turn(p, q, r):
    """Returns -1, 0, 1 if p,q,r forms a right, straight, or left turn."""
    return cmp((q[0] - p[0])*(r[1] - p[1]) - (r[0] - p[0])*(q[1] - p[1]), 0)

def _keep_left(hull, r):
    while len(hull) > 1 and turn(hull[-2], hull[-1], r) != TURN_LEFT:
            hull.pop()
    return (not len(hull) or hull[-1] != r) and hull.append(r) or hull

def _graham_scan(points):
    """Returns points on convex hull of an array of points in CCW order."""
    points.sort()
    lh = reduce(_keep_left, points, [])
    uh = reduce(_keep_left, reversed(points), [])
    return lh.extend(uh[i] for i in xrange(1, len(uh) - 1)) or lh

1 个答案:

答案 0 :(得分:3)

  1. _keep_left会返回一个列表hull,该列表最初为空。不向左转是从它上面移除的。当前点被添加到其中,除非它已经是列表中的最后一个元素。

  2. , [])是要减少的第三个参数。它是初始累加器值,将传递给_keep_left,从而使hull(最后,lhuh)最初为空。

  3. 它通过首先对点进行排序,然后两次遍历所有点(lhuh代表下半部分和上半部分)来执行Graham scan,并且每次扫描点数被累积到列表中。这些点与reduce一起累积,也就是说,结果原来是空的,并且这些点一个接一个地传递给_keep_left(按排序顺序),并且对于每个点,导致右边的点从累积列表中删除转弯。然后将当前点添加到累积列表中。

    _keep_left的返回值有点棘手:not len(hull)如果列表为空则返回True。 hull[-1] != r检查r(当前点)是否是列表中的最后一个元素。 hull.append(r)在布尔表达式中仅用于将r附加到列表的副作用(对我来说看起来有点脏),因此如果hull的最后一个元素是{{1} }},r将在不附加hull的情况下返回。

    换句话说,由于短路r将始终返回,但如果它不是最后一个元素,则会在返回之前附加hull。同样的逻辑应该更容易以更好,更冗长的方式实现。