【问题标题】:Conditional statement in a one line lambda function in python?python中单行lambda函数中的条件语句?
【发布时间】:2013-03-24 05:59:15
【问题描述】:

抱歉,如果以前有人问过这个问题,但我在任何地方都看不到。

基本上我遇到了一个场景,我需要在 lambda 函数中使用 if 语句。困难在于理想情况下它需要在一行代码中(如果可能的话?)

通常,我会这样写:

T = 250

if (T > 200):
    rate = 200*exp(-T)
else:
    rate = 400*exp(-T)

return (rate)

但是我需要它看起来像这样:

rate = lambda(T) : if (T>200): return(200*exp(-T)); else: return(400*exp(-T))

我意识到更容易做的事情是在 lambda 函数之外做出决策,然后为每种情况使用一个单独的 lambda 函数,但这并不适合这里。 lambda 函数存储在一个数组中,并在需要时访问,每个数组元素对应一个特定的“速率”,因此对于相同的“速率”有两个单独的行会搞砸。任何帮助将不胜感激,或者如果不可能,其他人的一些确认会很好:)

【问题讨论】:

  • 我怀疑你需要一个单行 lambda 函数,因为我怀疑你需要一个单行函数,我怀疑你需要一个 lambda 函数而不是命名函数。如果您要立即将函数名称命名为 rate,那么使用 lambda 有什么意义?
  • 太糟糕了,我只能 +1 DSM 一次......但要明确一点:更容易做的不是“在 lambda 函数之外做出决策”,而是将它们定义为首先是常规功能。您可以将常规函数存储在数组中。 lambdas 没有什么特别之处。它们是更有限的功能,而不是更强大的功能。
  • 那么函数需要放在一行中,我认为您不能使用命名函数来做到这一点?这些函数也存储为字符串,然后使用“eval”进行评估,我不确定如何使用常规函数。
  • 首先,为什么它需要放在一行中?其次,为什么将它们存储为字符串,然后使用eval 进行评估?这些都是非常糟糕的要求。我怀疑这里有一个XY problem,如果你告诉我们你真正想要做什么,我们可以解释正确的方法。

标签: python if-statement lambda ternary-operator conditional-operator


【解决方案1】:

使用exp1 if cond else exp2 语法。

rate = lambda T: 200*exp(-T) if T>200 else 400*exp(-T)

请注意,您不要在 lambda 表达式中使用 return

【讨论】:

    【解决方案2】:

    正确的做法很简单:

    def rate(T):
        if (T > 200):
            return 200*exp(-T)
        else:
            return 400*exp(-T)
    

    在这里使用lambda 绝对没有优势。 lambda 唯一的好处是允许您创建匿名函数并在表达式(而不是语句)中使用它们。如果您立即将 lambda 分配给变量,则它不再是匿名的,而是在语句中使用,因此您只是无缘无故地降低了代码的可读性。

    以这种方式定义的rate 函数可以以与 lambda 函数完全相同的方式存储在数组中、传递、调用等。它会完全一样(除了更容易调试、内省等)。


    来自评论:

    那么函数需要放在一行中,我认为您不能使用命名函数来做到这一点?

    我无法想象为什么函数需要放在一行中的任何充分理由。但可以肯定的是,您可以使用命名函数来做到这一点。在你的解释器中试试这个:

    >>> def foo(x): return x + 1
    

    这些函数也存储为字符串,然后使用“eval”进行评估,我不确定如何处理常规函数。

    再说一次,虽然很难 100% 确定你为什么要这样做,但我至少 99% 确定你没有理由或不好的理由这样做。几乎在任何时候您想将 Python 函数作为字符串传递并调用 eval 以便可以使用它们时,实际上您只是想将 Python 函数作为函数传递并将它们用作函数。

    但如果这确实是您需要的:只需使用 exec 而不是 eval

    您没有提及您使用的是哪个版本的 Python。在 3.x 中,exec 函数与eval 函数具有完全相同的签名:

    exec(my_function_string, my_globals, my_locals)
    

    在 2.7 中,exec 是一个语句,而不是一个函数——但您仍然可以使用与 3.x 中相同的语法来编写它(只要您不尝试将返回值分配给任何东西)和它有效。

    在早期的 2.x(我认为是 2.6 之前?)中,您必须这样做:

    exec my_function_string in my_globals, my_locals
    

    【讨论】:

      【解决方案3】:

      是的,您可以使用if 语句的简写语法。

      rate = lambda(t): (200 * exp(-t)) if t > 200 else (400 * exp(-t))
      

      请注意,您也不要在lambdas 中使用显式的return 语句。

      【讨论】:

      • 进一步缩短:rate = lambda(t): (200 if t > 200 else 400) * exp(-t)
      • @shahkalpesh 非常正确,尽管在说明问题的答案时可能不太明确。
      • “lambda”后面的括号也是多余的。
      【解决方案4】:

      我发现我可以在 lambda 中使用“if-then”语句。例如:

      eval_op = {
          '|'  : lambda x,y: eval(y) if (eval(x)==0) else eval(x),
          '&'  : lambda x,y: 0 if (eval(x)==0) else eval(y),
          '<'  : lambda x,y: 1 if (eval(x)<eval(y)) else 0,
          '>'  : lambda x,y: 1 if (eval(x)>eval(y)) else 0,
      }
      

      【讨论】:

        【解决方案5】:

        当你说rate = lambda whatever... 时,你已经打败了 lambda 的要点,应该只定义一个函数。但是,如果你想要一个 lambda,你可以使用 'and' 和 'or'

        lambda(T): (T>200) and (200*exp(-T)) or (400*exp(-T))
        

        【讨论】:

          【解决方案6】:

          如果你想更懒一点:

          #syntax lambda x : (false,true)[Condition]
          

          在你的情况下:

          rate = lambda(T) : (400*exp(-T),200*exp(-T))[T>200]
          

          【讨论】:

            猜你喜欢
            • 2021-05-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-04-03
            • 2015-03-04
            • 1970-01-01
            相关资源
            最近更新 更多