Распаковка разного количества переменных - PullRequest
0 голосов
/ 30 августа 2018

Я хочу сделать функцию гибкой в ​​отношении распаковки количества входных переменных.

Более конкретно, например, у меня есть следующее:

def flexi_func(vars):
    func_var_a, func_var_b, func_var_c, func_var_d = vars
    #do something

my_vars = [var_a, var_b, var_c, var_d]
flexi_func(my_vars)

Это прекрасно работает, если число входных переменных равно 4. Но, скажем, я хочу, чтобы одна и та же функция работала только с тремя или двумя входными переменными. Предположим, что бит «сделать что-то» уже гибкий. Затем, чтобы распаковать переменные, я могу написать

def flexi_func(vars):
    if len(vars) == 4:
        func_var_a, func_var_b, func_var_c, func_var_d = vars
    elif len(vars) == 3:
        func_var_a, func_var_b, func_var_c = vars
    elif len(vars) == 2:
        func_var_a, func_var_b = vars
    #do something

И это тоже отлично работает. Мне это кажется немного неуклюжим, особенно если бы у меня было N> 4 переменных. Есть ли более чистый, более Pythonic способ распаковать кортеж таким образом, чтобы я мог использовать распакованные переменные?

Я знаю по этот вопрос Я могу сделать что-то вроде этого (в Python 3):

foo, bar, *other = func()

но мне нужно было бы проделать больше работы для доступа к материалу в other, так что это не лучше, чем мой if...elif... подход.

1 Ответ

0 голосов
/ 30 августа 2018

Во-первых, в ответ на комментарии с просьбой указать контекст или конкретный пример, где это может быть необходимо, я допускаю, что почти во всех случаях, которые я могу придумать, должна быть возможность вообще избежать распаковки. Это касается и моей первоначальной проблемы - часть функции do something может быть изменена для доступа к элементам через индексы списка.

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

def flexi_func(var_list):    
    for i, var in enumerate(var_list):
        vars()['my_func_{}'.format(i)] = var

    #do something 

    return

Это присваивает каждую входную переменную встроенному словарю vars(). Это предпочтительнее встроенного словаря globals() и доступно для записи в отличие от встроенного словаря locals(). Чтобы получить доступ к переменным в разделе do something, вы должны ссылаться на словарь так: print(vars()['my_func_2']).

Наконец, если вы хотите использовать буквы в качестве меток переменных вместо цифр (как я это делал в моем заявлении о проблеме), вы можете добавить alphabet = [chr(i) for i in range(ord('a'),ord('z')+1)] в начало функции и вызвать переменные 'my_func_{}'.format(alphabet[i]).

...