Reputation: 1607
I have a function f
that takes in the arguments i
, A
and B
. i
is a counter and A
and B
are lists or constants. The function just adds the i-th element of A
and B
if they are lists. Here's what I have written in Python 3.
def const_or_list(i, ls):
if isinstance(ls, list):
return ls[i]
else:
return ls
def f(i, A, B):
_A = const_or_list(i, A)
_B = const_or_list(i, B)
return _A + _B
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
print(f(1, M, N)) # gives 13
print(f(1, M, P)) # gives 8
You will notice that const_or_list()
function is called on two (but not all) of the input arguments. Is there a decorator (presumably more Pythonic) approach to achieve what I am doing above?
Upvotes: 1
Views: 1040
Reputation: 49812
I think more pythonic in this case is not with a decorator. I would get rid of the isinstance
, use a try/except instead and get rid of the intermediate variables:
Code:
def const_or_list(i, ls):
try:
return ls[i]
except TypeError:
return ls
def f(i, a, b):
return const_or_list(i, a) + const_or_list(i, b)
Test Code:
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
Q = (5, 6, 7)
print(f(1, M, N)) # gives 13
print(f(1, M, P)) # gives 8
print(f(1, M, Q)) # gives 8
Results:
13
8
8
But I really need a decorator:
Fine, but it is a lot more code...
def make_const_or_list(param_num):
def decorator(function):
def wrapper(*args, **kwargs):
args = list(args)
args[param_num] = const_or_list(args[0], args[param_num])
return function(*args, **kwargs)
return wrapper
return decorator
@make_const_or_list(1)
@make_const_or_list(2)
def f(i, a, b):
return a + b
Upvotes: 1
Reputation: 108
You can do:
def const_or_list(i, ls):
if isinstance(ls, list):
return ls[i]
else:
return ls
def f(*args):
i_ip = args[0]
result_list = []
for i in range(1, len(args)):
result_list.append(const_or_list(i_ip, args[i]))
return sum(result_list)
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
print(f(1, M, N)) # gives 13
print(f(1, M, P)) # gives 8
Upvotes: 0