2015-09-26 2 views
2

У меня есть эта функция, которая определяет и возвращает переменные a и b в зависимости от значения параметра orientation.Определение переменных эффективно в соответствии с параметром, который может принимать несколько значений.

 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 

Мой вопрос: есть ли более компактный и/или более эффективный способ сделать то же самое? и если есть лучший способ, что это?

+1

Почему существуют циклы? И откуда это происходит? –

+0

Были для циклов, потому что я взял код из гораздо более сложного. Я удалил их, потому что они не способствовали этому вопросу, спасибо. – Valence

ответ

1

Способ было бы использовать словарь. Пример -

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 в качестве ключа. Вы не должны использовать этот метод, если хотите, чтобы значения оценивались только при необходимости.

Demo -

>>> 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. 
1

Не, вероятно, будет быстрее, но более емким (и вызывает те же исключения, когда 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 
+0

Обратите внимание, что это было бы ошибкой, если ориентация не была между 1 и 8, но так будет и код OP. –

+0

Yup. Я сознательно отражал поведение; он вызывает тот же самый «NameError», что делает исходный код (упущение - просто черта гораздо более очевидная, поскольку есть только одно место 'a' и' b', а не 8). – ShadowRanger

3

Во-первых, петли не нужны; будут возвращены только значения, назначенные в последней итерации. Как только вы избавитесь от них, довольно легко увидеть рисунок:

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