python中的内联回调函数

Cap*_*ggz 6 python arrays callback

我希望能够定义一个 python 函数,该函数执行某种数据结构遍历并在每一步执行一些操作(在回调中定义)。这里有一个简单的例子来说明。

def min_value(list):
   m = 0
   for i in range(0, len(list)):
     if list[i] < m: m = list[i]
   return m
Run Code Online (Sandbox Code Playgroud)

这个例子是微不足道的,但如果我正在遍历一个 n 维数组、一个 numpy 数组,或者我想定义一个更复杂的方法来遍历数据结构,就会变得更加复杂。

我正在寻找类似于以下 JavaScript 的“pythonic”类似物,它执行相同的操作。

traverse = function(list, callback) {
   for(i = 0; i < list.length; i++) {
      callback(list[i])
   }
}

min_value = function(list) {
   m = 0
   traverse(list, function(element) {
      if(element < m) m = element
   });
}
Run Code Online (Sandbox Code Playgroud)

如果我想要一个函数max_value(list),只需将一行调整为 ,if(element > m) m = element而不必复制/粘贴我的遍历函数会很方便。在 python 中执行此操作的最佳方法是什么?

编辑(答案):在这里,我使用下面接受的答案来展示如何用 python 3 编写我的原始 JS 示例。显然有更好的方法可以找到标量列表的最小值,但这是我的模式寻找。

def traverse(list, callback):
   for i in range(0, len(list)):
      callback(list[i])

def min_value(list):
   m = 0

   def update_min(val):
      nonlocal m
      if(val < m): m = val

   traverse(list, update_min)
   return m
Run Code Online (Sandbox Code Playgroud)

编辑(复杂示例):这是我的用例的一个更复杂和直接的示例。我有一个图像,我想对图像的“焦点区域”进行一些处理。比方说,例如,我想找到图像中最暗的 10x10、20x20、30x30 等像素区域。我的图像是一个 numpy 数组。我将使用“混蛋”多行 lambda 来说明我想要做什么,尽管据我所知 lambda 不能以这种方式使用。

在蟒蛇中:

# find the coordinates and of darkest region
def darkest_region(image, fsize):
   darkest_coords = [0, 0]
   darkest_avg = 256

   # illegal lambda
   g = lambda x, y, r:
      # r is an fsize x fsize region
      avg_darkness = # blah blah, traverse and average pixels
      if(avg_darkness < darkest_avg): darkest_coords = [x, y]

   focus_scan(image, fsize, g)
   return darkest_coords

# scan all regions of fsize x fsize
def focus_scan(image, fsize, callback):
   height, width = image.shape[:2]
   for y in range(0, height - fsize):
     for x in range(0, width - fsize):
        focus = image[y:y+fsize, x:x+fsize]
        callback(x, y, focus)
Run Code Online (Sandbox Code Playgroud)

鉴于我不能有这样的多行 lambda,我认为我需要做的是对 的参数和返回值有点花哨,focus_scan以适应各种可能的输入/输出。在这个例子中,我可以传递焦点扫描darkest_avg并让它返回我正在寻找的坐标,但我可能想要传递标量以外的其他东西,或者让它返回更复杂的数据结构。我想我将不得不做这样的事情:

def focus_scan(image, fsize, callback, args):
   ... # loopy loops
      some_result = callback([x, y, focus], args)

   return some_result
Run Code Online (Sandbox Code Playgroud)

我喜欢可以在其他编程语言中使用的内联函数方法,但它看起来不像是 Python 中的常见模式。

skr*_*krx 3

只需使用普通函数而不是多行 lambda 即可。要访问变量,darkest_coords您可以在 Python 3 中使用nonlocal关键字。在 Python 2 中,您必须更改列表,因为关键字nonlocal不可用。

def darkest_region(image, fsize):
    """Find the coordinates of darkest region."""
    darkest_coords = [0, 0]
    darkest_avg = 256

    def g(x, y, r):
        nonlocal darkest_coords
        # r is an fsize x fsize region
        avg_darkness = # blah blah, traverse and average pixels
        if avg_darkness < darkest_avg:
            darkest_coords = [x, y]

    focus_scan(image, fsize, g)
    return darkest_coords


def focus_scan(image, fsize, callback):
    """Scan all regions of fsize x fsize."""
    height, width = image.shape[:2]
    for y in range(0, height - fsize):
        for x in range(0, width - fsize):
            focus = image[y:y+fsize, x:x+fsize]
            callback(x, y, focus)
Run Code Online (Sandbox Code Playgroud)