Переключить / Case в Matlab на If / Else Python

1

Я работаю над переводом кода из Matlab в Python. В настоящее время я работаю над этим:

switch SIGNATURES_TYPE
    case 1
        rand('seed',5);
        load('USGS_1995_Library')
        wavlen=datalib(:,1);    % Wavelengths in microns
        [L n_materiais]=size(datalib);
        # select randomly
        sel_mat = 4+randperm(n_materiais-4);
        sel_mat = sel_mat(1:p);
        M = datalib(:,sel_mat);
        # print selected endmembers
        clear datalib wavelen names aux st;
    case 2
        error('type not available')
    case 3
        M = rand(L,p);
    case 4
        M = randn(L,p);
    case 5
        L=p;
        M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
    case 6
        L=p;
        M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
        A = randn(p);
        [U,D,V] = svd(A);
        M = U*M*V';
        clear A U D V;
    otherwise
        error('wrong signatute type')
end

Раньше я работал над аналогичным кодом Switch/Case:

for i=1:2:(length(varargin)-1)
    switch upper(varargin{i})
        case 'MM_ITERS'
            MMiters = varargin{i+1};
        case 'SPHERIZE'
            spherize = varargin{i+1};

Последнее я смог перевести на это:

for i in range(1, 2, length(*args)-1):
        if (arg[i].upper() == "MM_ITERS"):
            MMiters = arg(i+1)
        elif (arg[i].upper() == "SPHERIZE"):
            spherize = arg(i+1)

Однако для первого мне интересно, как я могу создавать похожие if-заявления. Например, для первого случая мой код может выглядеть примерно так:

if SIGNATURES_TYPE == 0:
    ** finish function

Я хотел бы знать, работает ли что-то подобное, или если было бы лучше разделить высказывания на отдельные функции, а затем называть их?

Спасибо за помощь и ввод!

  • 1
    Прямой перевод - просто if SIGNATURES_TYPE == 1: elif SIGNATURES_TYPE == 2: и т. Д. Есть ли причина, которая недостаточно хороша?
  • 1
    Вы также можете использовать словарь, чтобы эмулировать функциональность регистра, если вам не нравится if / elif / else
Показать ещё 1 комментарий
Теги:
if-statement
switch-statement

1 ответ

2
Лучший ответ

Конструкция if/else будет работать. Другой способ сделать это - использовать dict где ключи являются типами подписи, а значения - это функции, возвращающие M Это имеет то преимущество, что вам ничего не нужно. Таким образом, это будет выглядеть примерно так:

def case1(p):
    # calculate L and M
    return L, M

def case6(p):
    # calculate M
    return p, M

try:
    L, M = {1: case1(p),
            3: (L, np.random.rand(L, p)),
            4: (L, np.random.randn(L,p)),
            5: (p, np.diag(np.linspace(1,(1/(COND_NUMBER)**(1/DECAY)),p)**DECAY),
            6: case6(p)}[SIGNATURES_TYPE]
except KeyError:
    raise ValueError('Wrong signatute type: {}'.format(SIGNATURES_TYPE))

Что касается вашего предыдущего примера, код MATLAB является обходным решением для отсутствия обработки аргументов по умолчанию. Python имеет обработку аргументов по умолчанию, поэтому вам вообще не нужен if/else или loop. Вы можете просто сделать что-то вроде:

def myfunc(arg1, arg2, arg3, MM_ITERS=MM_ITERS_default, SPHERIZE=SPHERIZE_default):

где arg1, arg2 и arg3 - необходимые аргументы (число не имеет значения, может быть даже нулевой). MM_ITERS_default и SPHERIZE_default - это значения, которые вы хотите, чтобы соответствующие переменные SPHERIZE_default, когда пользователь не определяет их. Вы можете даже собрать аргументы непосредственно в dict, используя:

def myfunc(arg1, arg2, arg3, **kwargs):

Затем вы можете получить доступ, скажем, MM_ITERS, просто используя что-то вроде:

if MM_ITERS in kwargs:
    MM_ITERS = kwargs[MM_ITERS]'

Или же

MM_ITERS = kwargs.get(MM_ITERS, MM_ITERS_default)

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

  • 0
    Спасибо за помощь! Это было очень ясно. Я новичок как в Matlab, так и в Python и не мог понять необходимость использования аргументов командной строки в коде Matlab. Просто чтобы уточнить: если бы я должен был установить значение переменной по умолчанию в определении функции, когда метод на самом деле вызывается с другим значением, это значение будет использоваться методом?
  • 1
    @ А. Торрес: Да. myfunc(val1, val2, val3) , вы вызываете myfunc(val1, val2, val3) , тогда переменная MM_ITERS будет иметь MM_ITERS_default а SPHERIZE будет SPHERIZE_default . С другой стороны, если вы вызвали myfunc(val1, val2, val3, val4) , то у MM_ITERS будет val4 а у SPHERIZE будет SPHERIZE_default . И myfunc(val1, val2, val3, val4, val5) , имеет val4 для MM_ITERS и val5 для SPHERIZE . Вы также можете сделать, например, myfunc(val1, val2, val3, SPHERIZE=val5) , в этом случае переменная MM_ITERS будет иметь MM_ITERS_default а SPHERIZE будет иметь val5 .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню