2017-09-13 67 views
0

這是一個稍微普遍的問題 - 我在尋找最Python的和/或有效的方法:Python的使用迭代和條件的

我有一個大的數據集和數量,有時需要執行的任務通過迭代遍歷行,有時不需要,取決於某些條件。

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和最有效的方法?

回答

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) 
+0

喜歡這個 - pythonic和高效。 – doctorer

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) 

我想這是提高效率的問題,而不是什麼會是更Python。

我想這將是更Python:

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() 
+0

謝謝。是的,這樣更有效率。我想我正在尋找效率*和* pythonicity(?)。 – doctorer

+0

@doctorer謝謝,現在它有點pythonic,甚至更高性能。 –

0

我認爲首先是更Python的方法。但如果你真的想跳過迭代,如果沒有條件滿足,你可以添加一個break語句:

for ... : 
    if not any(condition 1, condition2): 
     break 
    else: 
     if condition1: 
      ... 
     if condition2: 
      ... 

這將使您避免在第一步迭代,或者檢查這兩個條件,如果任何滿足。

(抱歉格式,可以從手機打字)

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)