以Pythonic方式选择一个函数

时间:2014-04-25 22:26:16

标签: python python-3.x

假设我有以下变量:

x
y

和功能:

def runx(x):
    print(x)

def runy(y):
    print (y)

def runxy(x, y):
    print(x + y)

def nonexy():
    print('none')

基于下一个要求选择函数的Pythonic方法是什么:

- 如果value仅大于y运行功能runy

- 如果value仅大于x运行功能runx

- 如果value大于xy,则运行func runxy

- 如果value不比x更好,而y则不如nonexy

valuexy可以是任意数字

示例:

x = 4
y = 6
value = 5

此处value仅大于x,因此请runx(x)

6 个答案:

答案 0 :(得分:7)

if value > y :
    if value > x :
        runxy(x, y)
    else :
        runy(y)
else :
    if value > x :
        runx(x)
    else :
        nonexy()

我错过了什么吗?

答案 1 :(得分:6)

经常被遗忘的一种方法是使用逻辑表。现在,虽然我认为这是最好的方法,但我觉得这很有意思,所以这里采取或留下你想做的事。

             value > y   value <= y
             ----------  ----------
value > x  | runxy       runx
value <= x | runy        nonex

然后我们可以将其编成原样,利用函数是一等值的事实:

arr = [[runxy, runx], [runy, nonex]]

并按原样访问:

col = 0 if value > y else 1
row = 0 if value > x else 1
fn = arr[row][col]

然后只需编辑当前设计,例如 all 函数应该采用x和y参数(或使用上表中的包裹lambda)和..

fn(x, y)

答案 2 :(得分:3)

if value > y and value <= x:
    runy(y)
elif value <= y and value > x:
    runx(x)
elif value > x and value > y:
    runxy(x, y)
else:
    nonexy()

没有真正好的方法来处理这种模式,只是写出if / else块。

答案 3 :(得分:2)

比其他答案更难以理解,但对某些人来说可能很有趣:

def fn_picker(value, x, y):
    functions = { # lambdas to make it shorter
        0: lambda kwargs: 'none',
        1: lambda kwargs: kwargs['x'],
        2: lambda kwargs: kwargs['y'],
        3: lambda kwargs: kwargs['x'] + kwargs['y']
    }
    key = sum([(value > x), (value > y)*2]) # True is 1, False is 0
    fn = functions[key]
    return fn(locals())

print(fn_picker(5, 4, 6))

答案 4 :(得分:1)

如果所有函数都将x,y作为参数,则可以使用:

(nonexy,runx,runy,runxy)[1*(x<=value<=y)+2*(y<=value<=x)+3*(x<value>y)](x,y)

答案 5 :(得分:1)

我们定义一个字典,它将布尔对映射到lambda表达式。
布尔对是一个两元组,表示函数选择标准。
lambda表达式包含一个函数。需要x y,并调用该函数 用它需要的参数。

现在,我们可以定义一个结合了上面定义的工具的函数。

mapping = {
    (True, True): lambda x,y: runxy(x,y),
    (True, False): lambda x,y: runx(x),
    (False, True): lambda x,y: runy(y),
    (False, False): lambda x,y: nonexy()
}

def f(x, y, value):
    mapping[value > x, value > y](x,y)


请注意,只需定义mapping一次就足够了,无论我们想要运行任务多少次。这就是为什么我们把它放在f之外。 (无需在每次运行任务时定义它。)