Python для C# уменьшить понимание функции

Я изо всех сил пытаюсь понять вызов "Reduce", написанный ниже в Python.

Я нашел несколько источников, как здесь, так и в других местах, в которых говорится о том, что делает функция, и что существует эквивалентный "агрегат" для списков в C#, но я не могу понять, что на самом деле делают вызовы ниже -expect-... возможно потому что я не могу понять, что возвращает _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 ответ

Решение
  1. _keep_left возвращает список hull, который изначально пуст. Повороты, не идущие влево, удаляются из него. Текущая точка добавляется в нее, если только она не является последним элементом в списке.

  2. , []) это третий параметр, чтобы уменьшить. Это начальное значение аккумулятора, которое будет передано _keep_leftтаким образом делая hull (и в конце, lh а также uh) изначально пусто.

Он выполняет сканирование Грэма, сначала сортируя точки, а затем дважды просматривая все точки (lh а также uh обозначает нижнюю и верхнюю половину), и с каждым размахом очки накапливаются в списке. Очки накапливаются с reduceто есть результат изначально пустой, а баллы передаются _keep_left один за другим (в отсортированном порядке), и для каждой точки точки, вызывающие поворот вправо, удаляются из накопленного списка. Затем текущая точка добавляется в накопленный список.

Возвращаемое значение из _keep_left немного сложнее: not len(hull) возвращает True, если список пуст. hull[-1] != r проверяет, если r (текущая точка) является последним элементом в списке. hull.append(r) находится в логическом выражении только для побочного эффекта добавления r в список (выглядит немного грязным для меня), так что если последний элемент hull является r, hull будут возвращены без добавления r к этому.

Другими словами, из-за короткого замыкания hull всегда будет возвращен, но r будет добавлено к нему перед возвратом, если это не последний элемент. Та же самая логика должна быть легко реализована более хорошим, но более многословным способом.

Другие вопросы по тегам