以Pythonic方式选择函数

以Pythonic方式选择函数,python,python-3.x,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方法是什么: -如果值仅大于y,则运行func runy -如果值仅大于x,则运行func runx -如果值大于x和y,则运行func runxy -如果值不大于x且y,则

假设我有以下变量:

x
y
和功能:

def runx(x):
    print(x)

def runy(y):
    print (y)

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

def nonexy():
    print('none')
根据下一个需求选择函数的Pythonic方法是什么:

-如果值仅大于y,则运行func runy

-如果值仅大于x,则运行func runx

-如果值大于x和y,则运行func runxy

-如果值不大于x且y,则运行func nonexy

值x,y可以是任何数字

例如:

x = 4
y = 6
value = 5
这里的值只大于x,所以运行runxx

我错过什么了吗

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块之外,没有真正好的方法来处理这种模式。

一种经常被遗忘的方法是使用逻辑表。现在,虽然我不是在争论这是最好的方法,但我认为这很有趣,所以在这里走或走你想做的事。
             value > y   value <= y
             ----------  ----------
value > x  | runxy       runx
value <= x | runy        nonex
并访问它,以便:

col = 0 if value > y else 1
row = 0 if value > x else 1
fn = arr[row][col]
然后只需编辑当前设计,这样所有函数都应采用x和y参数,或使用上表中的包装lambda,然后

fn(x, y)

比其他答案更过分,但对某些人来说可能很有趣:

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))

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

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

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

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

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)

请注意,仅定义一次映射就足够了,不管我们希望运行任务多少次。这就是为什么我们把它放在f之外。无需在每次运行任务时定义它。

为什么要这样做?我试图以某种方式表示我需要放入类中的功能,我需要验证一个值是否大于两个无变量,以正确选择methodNope。根据您是否需要返回值,您可以压缩内部语句以返回runxyx,y if value>x else runyy等@ErikAllik:我想是这样。这当然不是Hasshon@acomar:别忘了else if在Python中拼写为elif。这是因为它很圆滑,但对于一个四值问题来说可能有点过火:pfn=[nonexy,runy],[runx,runxy][value>x][value>y]
(nonexy,runx,runy,runxy)[1*(x<=value<=y)+2*(y<=value<=x)+3*(x<value>y)](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)