[英]Pythonic way to use the second condition in list comprehensions
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
. 如您所见,根据
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. 我不喜欢第3行和第5行几乎相同,并且不遵循DRY(不要重复自己)原则。 How can this code be improved?
如何改进此代码?
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
]
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: 您可以通过使用在第一种情况下仅返回
True
的函数和在第二种情况下实际将my_fun2
结果与par1
进行比较的函数来动态选择条件函数:
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: 或者,如果
par1
不是空字符串,则用生成器表达式替换外部循环:
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. 但是,不要让DRY使函数更难以读取,维护或调试。 I, personally, think that your approach is fine (and probably faster) and you probably shouldn't change anything.
我个人认为你的方法很好(可能更快),你可能不应该改变任何东西。
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.