Избегайте вложенных условий - PullRequest
1 голос
/ 06 августа 2020

Я разрабатываю программу, в которой я пытаюсь избежать вложенности условных операторов.

В основном у меня есть 2 набора из 3 параметров: a_changes, b_changes и c_changes - это логические значения, и они связаны с a, b и c, которые являются списками, если они меняются, или плавающими, если нет. Моя цель - преобразовать неизменяемые параметры в списки той же длины, что и изменяющиеся параметры.

Пример:

a_changes = True
b_changes = False
c_changes = False
a = [0.21, 0.25, 0.29]
b = 0.13
c = 0.78

становится

a_changes = True
b_changes = False
c_changes = False
a = [0.21, 0.25, 0.29]
b = [0.13, 0.13, 0.13]
c = [0.78, 0.78, 0.78]

Проблема is: несколько параметров могут изменяться одновременно, поэтому вы можете иметь:

a_changes = True
b_changes = True
c_changes = False
a = [0.21, 0.25, 0.29]
b = [0.13, 0.13, 0.13]
c = 0.78

становится

a_changes = True
b_changes = True
c_changes = False
a = [0.21, 0.25, 0.29]
b = [0.13, 0.13, 0.13]
c = [0.78, 0.78, 0.78]

Если несколько параметров изменяются, их длина одинакова, поэтому проблем не возникает оттуда. Однако я бы хотел избежать множества вложенных условных операторов. Это вообще возможно? Есть ли структура данных, которую я мог бы использовать?

Ответы [ 3 ]

1 голос
/ 06 августа 2020

Это должно работать, если хотя бы один вход является списком:

def refine_arguments(a, b, c, a_changes, b_changes, c_changes):

    # get the max len of one of the list (should be all the same listlenght)      
    maxlen = max(len(i) for i in (a, b, c) if isinstance(i, list))

    # if the X_changes is true use the float value times maxlen, else leave as is
    a = [a] * maxlen if not a_changes and not isinstance(a, list) else a
    b = [b] * maxlen if not b_changes and not isinstance(b, list) else b
    c = [c] * maxlen if not c_changes and not isinstance(c, list) else c

    return a, b, c


a_changes = True
b_changes = True
c_changes = False
a = [0.21, 0.25, 0.29]
b = [0.13, 0.13, 0.13]
c = 0.78

print(*refine_arguments(a, b, c, a_changes, b_changes, c_changes))

a_changes = True
b_changes = False
c_changes = False
a = [0.21, 0.25, 0.29]
b = 0.78
c = 0.78

print(*refine_arguments(a, b, c, a_changes, b_changes, c_changes))

Выход:

[0.21, 0.25, 0.29] [0.13, 0.13, 0.13] [0.78, 0.78, 0.78]
[0.21, 0.25, 0.29] [0.78, 0.78, 0.78] [0.78, 0.78, 0.78]

Используйте a,b,c = refine_arguments(a, b, c, a_changes, b_changes, c_changes) для работы с a, b, c позже по.

1 голос
/ 06 августа 2020

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

Сохраните ваши данные в списке:

data = [a, b, c]

Получить длина списка:

size = next((len(x) for x in data if isinstance(x, list)), 1)

Обратите внимание, что этот вызов next защищает от всех элементов, являющихся float, возвращая один. Теперь выполните преобразование:

for i in range(len(data)):
    if ~isinstance(data[i], list):
        data[i] = [data[i]] * size

Или более кратко:

data = [x if isinstance(x, list) else [x] * size for x in data]
1 голос
/ 06 августа 2020

Структура данных, которую вы можете использовать, - это numpy массивы. Если у вас много параметров, используйте словарь, чтобы разрешить l oop операции:

my_data = {}

my_data["a"] = [0.21, 0.25, 0.29]
my_data["b"] = 0.13
my_data["c"] = 0.78

length = 1

for param in my_data:
    my_data[param] = np.array(my_data[param], ndmin=1) # at least 1d
    length = max(length, len(my_data[param]))

for param in my_data:
    my_data[param] = np.ones(length) * my_data[param] # make sure all is the same lentgh


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...