2015-11-06 25 views
2

對於不好的標題表示歉意。我不確定如何說出我的問題。 我有下面的代碼使用稱爲propadd的元組列表。 if statement測試元組的匹配條件。如果匹配只匹配元組列表中的1個元組,它將執行與if語句中相同的代碼,以便將此匹配元組分配給變量v,以便用來自此匹配元組的值更新遊標行。我想知道是否有辦法擺脫if語句後與v完全相同的代碼的賦值。在檢查匹配的長度時,是否可以在if語句中將列表分配給v?這是遵循這種方法的大量代碼的一部分。我相信這樣做會使我的代碼更快。分配變量名稱以列出if語句python

if len([item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500]) == 1: 
     v=[item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500] 
     row1[1]=v[0][1] 
     row1[2]=v[0][2] 
elif len([item for item in custadd if item[0]==row1[4]]) == 1: 
     k=[item for item in custadd if item[0]==row1[4]] 
     row1[1]=k[0][1] 
     row1[2]=k[0][2] 
elif len([item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()]) == 1 
     m=[item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()] 
     row1[1]=m[0][1] 
     row1[2]=m[0][2] 
+0

如果你想讓你的代碼更快,我相信使用'filter'函數比列表comp更快。當我打字的時候,@MadPhysicist發佈了我要說的話:你可以分配'v'然後檢查'len(v)',這樣list comp只運行一次 –

+0

我會研究'filter'函數。謝謝。 – ketar

回答

2

它會讓你的代碼稍微快一點,更重要的是,可讀性更強,更不容易出錯。無論您創建的列表是否通過測試len(...) == 1,它都會被計算。那麼爲什麼不計算一次呢?當然,你將不得不與else-if更換elif

# Compute v 
v = [item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500] 
if len(v) == 1: 
    row1[1]=v[0][1] 
    row1[2]=v[0][2] 
else: 
    # If v fails, compute k 
    k = [item for item in custadd if item[0]==row1[4]] 
    if len(k) == 1: 
     row1[1]=k[0][1] 
     row1[2]=k[0][2] 
    else: 
     # If k fails, compute m 
     m = [item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()] 
     if len(m) == 1: 
      row1[1]=m[0][1] 
      row1[2]=m[0][2] 

由C的到來,這是比if(v = (....)) { } else ...更加繁瑣。但是,還有另一種方法可以做到這一點。您可以使用一個事實,即在列表解析每個表達式是發電機:

v = (item for item in propadd if item[0]==row1[8] and harversine(custx,custy,item[2],item[3])<1500) 
k = (item for item in custadd if item[0]==row1[4]) 
m = (item for item in numlist if re.search(r"^[0-9]+(?=\s)",row1[0]) is not None and item[0]==re.search(r"^[0-9]+(?=\s)",row1[0]).group()) 
for gen in (v, k, m): 
    l = list(gen) 
    if len(l) == 1: 
     row1[1] = l[0][1] 
     row1[2] = l[0][2] 
     break 

在這種情況下,表達vkm是發電機,這是懶洋洋地evalutated iterables對象。他們實際上並沒有計算清單。你可以通過每一個,並找到匹配時找到,忽略其他人。直到陳述l = list(gen)纔會計算列表。我認爲第二種方法更多是Pythonic,因爲無論您擁有多少條件,它都使用一個for循環,而不是從頁面前進的一系列else語句。

+0

我有5個其他elif,檢查700,000行的不同條件。在這種情況下,我必須在if和elifs之外定義「v」。 (這些變量從這個v測試不同的條件)。如果這些代碼是針對每一行計算的,那真的會減慢代碼的速度,但是我希望這些v變量只能在第一個if和before之前的elifs失敗時計算,以便它們不會每次都創建。 – ketar

+0

你應該認識到,如果len([項目在propadd中item [0] == row1 [8]和harversine(custx,custy,item [2],item [3])<1500])== 1 '計算'v'的值並將其傳遞給'len()'?我所做的只是將一個指向列表的指針賦給一個臨時變量。 –

+0

此外,不要試圖優化你的代碼,直到你運行它,並知道有問題。可讀性比優化更重要。 –