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 ответ
_keep_left
возвращает списокhull
, который изначально пуст. Повороты, не идущие влево, удаляются из него. Текущая точка добавляется в нее, если только она не является последним элементом в списке., [])
это третий параметр, чтобы уменьшить. Это начальное значение аккумулятора, которое будет передано_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
будет добавлено к нему перед возвратом, если это не последний элемент. Та же самая логика должна быть легко реализована более хорошим, но более многословным способом.