2012-12-07 37 views
2

假設我有一個功能類似如下:嵌入式if語句

bigrams=[(k,v) for (k,v) in dict_bigrams.items() 
     if k[:pos_qu]==selection[:pos_qu] 
     and (k[pos_qu+1:]==selection[pos_qu+1:] if pos_qu!=1) 
     and k[pos_qu] not in alphabet.values()] 

我想要第二個條件,即k[pos_qu+1:]==selection[pos_qu+1:]依賴從另一個if語句,if pos_qu!=1。我試過(如上圖所示),通過包括兩項合計爲括號但蟒蛇標誌在括號中的語法錯誤

+3

只是一個評論,這是一個列表理解的複雜並不是非常pythonic。爲什麼不把它寫成標準的'for'和'list.append()'?另外,如果語句 –

+1

parens是有效的並且經常用於分組東西...,則括號在python中無效......但是不是必需的...(至少在py2中) –

+1

@BrianCray:從技術上講,本例中沒有if語句,只是列表理解中的if子句,它具有類似但不同的語法。 – abarnert

回答

2

如果我正確理解您的要求,您只想檢查k[pos_qu+1:]==selection[pos_qu+1:],如果條件pos_qu!=1也符合。你可以換一種說法爲以下條件:

pos_qu==1 or k[pos_qu+1:]==selection[pos_qu+1:] 

將這些放在你的理解:

bigrams=[(k,v) for (k,v) in dict_bigrams.items() 
     if k[:pos_qu]==selection[:pos_qu] 
     and (pos_qu==1 or k[pos_qu+1:]==selection[pos_qu+1:]) 
     and k[pos_qu] not in alphabet.values()] 
1

只是更改順序

bigrams=[(k,v) for (k,v) in dict_bigrams.items() 
    if k[:pos_qu]==selection[:pos_qu] #evaluated first 
    and pos_qu!=1 #if true continue and evaluate this next 
    and (k[pos_qu+1:]==selection[pos_qu+1:]) #if pos_qu != 1 lastly eval this 

的評論中提到,這不是一個很Python的列表理解並且作爲循環的標準將更具可讀性。

2

無論何時你發現自己有一個複雜的列表解析,試圖找出如何做複雜的,而不是知道如何,答案通常是分手。表達式語法本質上比Python中的完整語句(或多語句套件)語法更有限,以防止您編寫以後無法閱讀的內容。通常情況下,這是一件好事 - 即使不這樣做,最好還是繼續努力,而不是試圖與之抗爭。

在這種情況下,除了if子句,您不知道如何將其寫爲表達式,這種情況下的解釋很簡單。所以,我會把條件變成一個單獨的函數:

def isMyKindOfKey(k): 
    … condition here 
[(k,v) for (k,v) in dict_bigrams.items() if isMyKindOfKey(k)] 

這讓你使用完整的多語句語法的條件。它還可以讓你給這個條件一個名字(希望比isMyKindOfKey更好);使得閉包捕獲的參數,局部值更加明確;讓您單獨測試該功能或重新使用它;等等。

在循環本身是非平凡部分(或者只有很多嵌套)的情況下,將整個理解分解爲明確的for循環和append通常會更有意義,但是我不'我認爲這是必要的。

值得注意的是,在這種情況下 - 正如一般情況 - 這不會奇蹟般地解決您的問題,它只是爲您提供更大的靈活性。例如,你可以使用同樣的轉變,從後綴if到中綴or是FJ建議,但你也可以把它作爲一個if,例如,像這樣:

def isMyKindOfKey(k): 
    retval = k[:pos_qu]==selection[:pos_qu] 
    if pos_qu!=1: 
     retval = retval and (k[pos_qu+1:]==selection[pos_qu+1:]) 
    retval = retval and (k[pos_qu] not in alphabet.values()) 
    return retval 

這可能是不實際的方式,我'寫這個,但你可以看到這是一個微不足道的方式來將你的頭腦轉換成代碼,這在表達式中很難做到。