这是一个稍微普遍的问题 - 我正在寻找最具蟒蛇味和/或效率的方法:
我有一个大型数据集和一些有时需要通过遍历行执行的任务,有时候根本不需要,具体取决于某些条件。
for step in np.arange (0, number_of_steps):
if condition1:
do_calculation1(step)
if condition2:
do_calculation2(step)
因此,每次迭代都会重复if
个语句。整个数据集的条件为真或假,所以为了节省时间,如果不需要,我不会进行迭代:
if condition1 or condition2:
for step in np.arange (0, number_of_steps):
if condition1:
do_calculation1(step)
if condition2:
do_calculation2(step)
但我有时会不必要地重复if
次陈述。
另一种方法是分离条件语句,并在数据集中进行两次迭代:
if condition1 :
for step in np.arange (0, number_of_steps):
do_calculation1(step)
if condition2:
for step in np.arange (0, number_of_steps):
do_calculation2(step)
这样做的缺点是,如果两个条件都为真,我会迭代两次,这很慢(而且很笨拙)。两种方法的相对速度将取决于每种条件的真实频率,但我将使用各种各样的数据,因此我不知道哪种更快。
所以我的问题是哪种方法是最具有pythonic和最有效的方法?
答案 0 :(得分:3)
这就是我要做的事情:
calculations = [
f for c,f in [
(condition1, do_calculation1),
(condition2, do_calculation2),
] if c
]
if calculations:
for step in np.arange (0, number_of_steps):
for calc in calculations:
calc(step)
答案 1 :(得分:1)
您可以简单地结合两种方法:
if not condition1 and not condition2:
pass
elif not condition1 and condition2
for step in np.arange (0, number_of_steps):
do_calculation1(step)
elif condition1 and not condition2:
for step in np.arange (0, number_of_steps):
do_calculation2(step)
else: # condition 1 and condition2:
for step in np.arange (0, number_of_steps):
do_calculation1(step)
do_calculation2(step)
我想这更像是一个效率问题,而不是更多的pythonic。
我想这会更加pythonic:
def run_calcs(number_of_steps, *funcs):
for step in range(number_of_steps):
for func in funcs:
func(step)
def gen_func_list(condition1=False, condition2=False):
func_list = []
if condition1:
func_list.append(do_calculation1)
if condition2:
func_list.append(do_calculation2)
return func_list
if __name__ == '__main__':
number_of_steps = 10
run_calcs(
number_of_steps,
*gen_func_list(
condition1=<your condition here>,
condition2=<your condition here>
)
)
我认为这也非常易读,适合多处理:
from multiprocessing import Process
def run_calcs(number_of_steps, *funcs):
for step in range(number_of_steps):
for func in funcs:
func(step)
def gen_func_list(condition1=True, condition2=True):
func_list = []
if condition1:
func_list.append(do_calculation1)
if condition2:
func_list.append(do_calculation2)
return func_list
if __name__ == '__main__':
number_of_steps = 10
funcs = gen_func_list(
condition1=<your condition here>,
condition2=<your condition here>
)
proc_handles = []
for f in funcs:
proc_handles.append(
Process(target=run_calcs,
args=[number_of_steps, f])
)
for p in proc_handles:
p.start()
for p in proc_handles:
p.join()
答案 2 :(得分:0)
我认为第一种是更加pythonic的方法。但是如果你真的想在没有条件的情况下跳过迭代,你可以添加一个break语句:
for ... :
if not any(condition 1, condition2):
break
else:
if condition1:
...
if condition2:
...
这将允许您避免第一步的迭代,或检查两个条件是否满足。
(抱歉格式化,从手机输入。)
答案 3 :(得分:0)
我认为第一种方法是最好的,因为您的数据集要么具有条件(1和/或2)。
for step in np.arange (0, number_of_steps):
if condition1:
do_calculation1(step)
if condition2:
do_calculation2(step)
如果这两个条件是互斥的,那么你可以用elif替换第二个条件。这将节省一些计算。
for step in np.arange (0, number_of_steps):
if condition1:
do_calculation1(step)
elif condition2:
do_calculation2(step)