0

我的代码包含多行嵌套 for 循环。我想尝试通过将代码放入类似于do_for_each下面的函数的自己的函数中来减少调用的嵌套 for 循环的数量。在嵌套的 for 循环中,我想调用另一个函数。下面是一个工作示例:

def do_for_each(self, func, h, w, init_data):
        for x in range(1, h):
            for y in range(1, w):
                init_data[x,y] = func(x, y)
        return init_data

def calculate_land_neighbours(self, x, y):
        return self.lscape[x-1,y] + self.lscape[x+1,y] + self.lscape[x,y-1] + self.lscape[x,y+1]

ouput = self.do_for_each(self.calculate_land_neighbours, self.h+1, self.w+1, data)

do_for_each但是,当调用的函数不带参数xy另一个变量时,我的问题就出现了。例如,一个新函数如下所示:

def add_to_density_array(self, seed):
        if seed == 0:
            return 0
        else:
            return random.uniform(0, 5.0)

output2 = self.do_for_each(self.add_to_density_array, self.h+1, self.w+1, data, seed)

为了使其正常运行,我需要将我的do_for_each功能修改为:

def do_for_each(self, func, h, w, init_data, seed):
        for x in range(1, h):
            for y in range(1, w):
                init_data[x,y] = func(seed)
        return init_data

有人有什么建议可以让我保留do_for_each函数的模块化代码,但在其中调用函数do_for_each没有相同的输入参数吗?

4

3 回答 3

1

从根本上说,您的两个do_for_each功能非常不同。它们根本没有真正执行相同的转换——一个将矩阵条目更改为x,y索引的函数,而另一个则没有。

我会考虑在这里使用不同的抽象。

也就是说,您可以在不更改原始内容的情况下完成这项工作do_for_each:传递一个包装的 lambda add_to_density_array,而不是直接传递后者:

add_to_density = lambda x, y: self.add_to_density_array(seed)
output2 = self.do_for_each(add_to_density, self.h+1, self.w+1, data)
于 2020-09-19T10:28:41.250 回答
0

您可以使用seedas的默认参数None并检查它是否退出并进行相应操作:

def do_for_each(self, func, h, w, init_data, seed=None):
    for x in range(1, h):
        for y in range(1, w):
            # If no seed provided
            if seed is None:
                init_data[x, y] = func(x, y)
            # Else, seed provided - use it
            else:
                init_data[x, y] = func(seed)
    return init_data

这具有向后兼容“旧”的优点do_for_each(self, func, h, w, init_data)

于 2020-09-19T10:17:44.437 回答
0

您可以尝试重载函数,这是一个可能的解决方案。您可以在此处阅读更多信息 - https://www.geeksforgeeks.org/python-method-overloading/

def do_for_each(self, func, h, w, init_data, seed=None):
    if seed==None:
        for x in range(1, h):
            for y in range(1, w):
                init_data[x,y] = func(x, y)
        return init_data
    else:
        for x in range(1, h):
            for y in range(1, w):
                init_data[x,y] = func(seed)
        return init_data
于 2020-09-19T10:31:13.700 回答