Reputation: 371
Let's assume the following function:
def myfun(my_list, n, par1=''):
if par1 == '':
new_list = [[my_fun2(i,j) for j in range(n)] for i in range(n)]
else:
new_list = [[my_fun2(i,j) for j in range(n)] for i in range(n) if my_fun2(i,n) == par1]
return new_list
As you can see, there are two different scenarios depending on par1
. I do not like that line 3 and line 5 are almost identical and do not follow the DRY (Don't Repeat Yourself) principle. How can this code be improved?
Upvotes: 9
Views: 981
Reputation: 1914
This might work:
new_list = [[my_fun2(i,j) for j in range(n)] for i in range(n) if par1 == '' or my_fun2(i,n) == par1]
So used like this:
def myfun(my_list, n, par1=''):
return [
[my_fun2(i,j) for j in range(n)]
for i in range(n) if par1 == '' or my_fun2(i,n) == par1
]
Upvotes: 8
Reputation: 152587
You could choose the condition function dynamically by using a function that just returns True
in the first case and one that actually compares the my_fun2
result with par1
in the second case:
def myfun(my_list, n, par1=''):
if par1 == '':
cond = lambda x, y: True
else:
cond = lambda i, n: my_fun2(i, n) == par1
return [[my_fun2(i,j) for j in range(n)] for i in range(n) if cond(i,n)]
Or by replacing the outer loop with a generator expression in case par1
isn't an empty string:
def myfun(my_list, n, par1=''):
if par1 == '':
outer = range(n)
else:
# a conditional generator expression
outer = (i for i in range(n) if my_fun2(i,n) == par1)
return [[my_fun2(i,j) for j in range(n)] for i in outer]
However don't let DRY make the function harder to read, maintain or debug. I, personally, think that your approach is fine (and probably faster) and you probably shouldn't change anything.
Upvotes: 8
Reputation: 13672
why not use a filter ?
from operator import eq
def myfun(my_list, n, par1=''):
new_list = ([my_fun2(i,j) for j in range(n)] for i in range(n))
if par1 != '':
new_list = filter(eq(par1),new_list)
return list(new_list)
Upvotes: 1