【问题标题】:Defining variables efficiently according to a parameter that may take several values根据可能取多个值的参数有效地定义变量
【发布时间】:2015-09-26 02:58:37
【问题描述】:

我有这个函数,它根据参数orientation 的值定义并返回变量ab

        def myfunc(orientation, l, w):


            if orientation == 1:
                a = -w
                b = l
            elif orientation == 2:
                a = -l
                b = w
            elif orientation == 3:
                a = -w
                b = -l
            elif orientation == 4:
                a = -l
                b = -w
            elif orientation == 5:
                a = w
                b = l
            elif orientation == 6:
                a = l
                b = w
            elif orientation == 7:
                a = w
                b = -l
            elif orientation == 8:
                a = l
                b = -w

            return a, b

我的问题是:有没有更紧凑和/或更有效的方法来做同样的事情?如果有更好的方法,是什么?

【问题讨论】:

  • 为什么会有for循环? l,w 是从哪里来的?
  • 有 for 循环,因为我从一个更复杂的代码中获取了代码。我删除了它们,因为它们对问题没有贡献,谢谢。

标签: python function variables python-3.x


【解决方案1】:

首先,循环是不必要的;只有在最后一次迭代中分配的值才会被返回。一旦你摆脱了这些,就很容易看到模式:

def myfunc(orientation, l, w):

    a, b = (w, l) if orientation % 2 else (l, w)

    if orientation <= 4:
        a = -a
    if orientation in (3, 4, 7, 8):
        b = -b

    return a, b

【讨论】:

    【解决方案2】:

    一种方法是使用字典。示例 -

    def myfunc(orientation, l, w):
        return { 1: (-w, l), 2: (-l, w), 3: (-w, -l),
                 4: (-l, -w), 5: (w, l), 6: (l, w),
                 7: (w, -l), 8: (l, -w) }[orientation]
    

    请注意,这会评估字典中所有可能的值,然后根据 orientation 作为键选择要返回的适当值。如果希望仅在需要时评估值,则不应使用此方法。

    演示 -

    >>> def myfunc(orientation, l, w):
    ...     return {1: (-w, l), 2: (-l, w), 3: (-w, -l),
    ...             4: (-l, -w), 5: (w, l), 6: (l, w),
    ...             7: (w, -l), 8: (l, -w)}[orientation]
    ...
    >>> myfunc(3,3,4)
    (-4, -3)
    

    如果找不到密钥,上述内容将以 KeyError 结尾。如果您可能以字典中未找到的方向调用此函数,则可以使用 .get(key, default) 使其返回一些默认值或其他默认值。示例 -

    def myfunc(orientation, l, w):
        return { 1: (-w, l), 2: (-l, w), 3: (-w, -l),
                 4: (-l, -w), 5: (w, l), 6: (l, w),
                 7: (w, -l), 8: (l, -w) }.get(orientation) #This returns `None` if orientation is not found in the dictionary. Use `.get(orientation, defaultval)` for some other default value.
    

    【讨论】:

      【解决方案3】:

      不太可能更快,但更简洁(当orientation 为“无效”时会引发相同的异常):

      def myfunc(orientation, l, w):
          if 1 <= orientation <= 8:
              a = (-w, -l, -w, -l, w, l, w, l)[orientation - 1]
              b = (l, w, -l, -w)[(orientation - 1) % 4]
      
          return a, b
      

      【讨论】:

      • 请注意,如果方向不在 1 和 8 之间,则会出错,但 OP 的代码也会出错。
      • 是的。我故意模仿行为;它引发了与原始代码相同的NameError(省略只是更明显,因为只分配了一个位置ab,而不是8个)。
      猜你喜欢
      • 2013-04-30
      • 1970-01-01
      • 2016-04-18
      • 1970-01-01
      • 2015-06-08
      • 2019-06-12
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多