将可变数量的参数应用于许多函数之一

时间:2017-01-03 19:30:20

标签: python python-3.x

我有一组可以在数据结构上运行的函数,其中以预定的概率选择给定的函数。我这样做是通过为列表中的每个分配一个正整数,itertools.accumulate - 权重,然后bisect - 进入列表:

func_weights = list(accumulate(weights))
probability = bisect(func_weights, random.random() * func_weights[-1])

问题在于,每个函数都有一组略有不同的参数/参数。其中一些只需要数据结构,其中一些需要来自程序其余部分的附加信息。现在,我将每个调用的附加信息构建到字典中,并作为func[probability](data_struct, **arguments)传递给函数,这样我就可以使每个函数看起来像:

funcs = [func_1, func_2, func_3, ...]
weights = [1, 2, 3, ...]

func_weights = list(accumulate(weights))
probability = bisect(func_weights, random.random() * func_weights[-1])
funcs[probability](data_struct, **arguments)

# ...

def func_1(data_s, arg_1, **kwargs):
    # blah blah blah

def func_2(data_s, arg_2, **kwargs):
    # blah blah blah

def func_3(data_s, arg_1, arg_2, **kwargs):
    # blah blah blah

这很好用,当我最终完成所有设置时我觉得非常聪明,但我稍微改变了data_structure,现在重新思考这个装置的两个部分:

  • 首先,一些参数是随机数,所以不是在所有函数中调用random.random(),而是在build_arguments()中调用一次。我有没有想过这个?

  • 第二,设置一个精心设计的开关式语句而不是**arguments的东西会更聪明吗?切入索引,获取func名称,然后if-then正确的函数。

示例:

if name == 'func_1':
    func_1(data_struct, arg_1)
elif name == 'func_2':
    func_2(data_struct, arg_2)
elif name == 'func_3':
    func_3(data_struct, arg_1, arg_2)
# etc etc
  • 第三,除此之外,所有这些功能都直接对结构内的数据进行操作,而不是纯粹的。传递将被修改的元素而不是整个data_structure会更聪明吗?

示例:

func_3(data_struct, arg_1, arg_2)

# ...

def func_3(data_s, arg_1, arg_2, **kwargs):
    alist = data_s.alist
    temp = alist[:arg_1] + alist[arg_2:]
    point = random.randint(len(temp))
    data_s.alist[:] = temp[:point] + alist[arg_1:arg_2] + temp[point:]

data_s[:] = func_3(data_struct.alist, arg_1, arg_2)

# ...

def func_3(alist, arg_1, arg_2, **kwargs):
    temp = alist[:arg_1] + alist[arg_2:]
    point = random.randint(len(temp))
    return temp[:point] + alist[arg_1:arg_2] + temp[point:]

非常感谢!

编辑:似乎存在一些混乱。我修正了一个小错误,但除此之外,它的工作原理如3.4和3.5中所述,如in this gist I just created所示。

1 个答案:

答案 0 :(得分:0)

如果我对您的问题的解释是正确的,您可能希望以此为基础。

我的解释是你希望运行具有正确数量的参数的许多函数之一,随机选择函数并随机生成参数。

您必须明确更改功能选择以匹配您的概率模型。

import inspect
import random

def func1():
    pass

def func2():
    pass

def func3():
    pass

functions = [
  func1, func2, func3
]

random_func = random.choice(functions)
random_args = [random.randint(1, 10) for i in range(len(inspect.getfullargspec(random_func).args))]
random_func(*random_args)