Python - 用于非离散比较的交换机替代方案

Ben*_*son 2 python dictionary switch-statement

也许之前已经问过这个问题,但我找不到它.我正在尝试实现一些确定给定值的范围的东西.在这个例子中,x可以是任何实数.

def f(x):
    if x < 0.1:
        do_something_1()
    elif 0.1 <= x < 1:
        do_something_2()
    elif 1 <= x < 10:
        do_something_3()
    elif x >= 10:
        do_something_4()
Run Code Online (Sandbox Code Playgroud)

......你明白了.

我已经看到很多字典替换Python中的switch语句的例子,但我总是将字典理解为索引离散值.

我发现很难相信if-elif-else链是这种情况下的最佳解决方案.有谁知道更好的一个?

Sve*_*ach 12

一种简单的改进方法就是不重复下限.你的代码相当于

if x < 0.1:
    do_something_1()
elif x < 1:
    do_something_2()
elif x < 10:
    do_something_3()
else:
    do_something_4()
Run Code Online (Sandbox Code Playgroud)

如果真的有很多值,你可能想要bisect改为,但只有四个选项,上面的代码可能是最好的解决方案,至少在可读性和速度方面.

  • @poorsod:不同的解决方案适用于不同的制度,因为它们的规模不同.如果你举一个简短的例子 - 这很好,顺便说一句! - 那么请提一下你真正问题所涉及的尺码. (5认同)
  • @poorsod:那26个范围有一个模式吗?或者它们是由任意常数定义的?如果是前者,请使用模式来简化代码.如果是后者,请使用`bisect`. (3认同)
  • 非常欢迎你.请注意,即使您没有听说过bisect,这最好在for循环中解决,将每个与'x'进行比较并跟踪索引,而不是使用26-clause if/elif语句.这是[XY问题]的一个很好的例子(http://www.perlmonks.org/?node_id=542341).干杯! (2认同)

Dav*_*son 9

使用bisect包查找值所在的索引,然后调用相应的函数.在你的例子中:

import bisect

def f(x):
    funcs = [do_something_1, do_something_2, do_something_3, do_something_4]
    funcs[bisect.bisect_left([.1, 1, 10], x)]()
Run Code Online (Sandbox Code Playgroud)