2012-06-26 28 views
2

我正在嘗試輸入一個沒有設置結果代碼的函數。我可以通過混合到stderr流中的「error:」字符串來告訴它失敗,通常在不同的轉換狀態消息的中間。使用中間結果的嵌套列表理解

我有以下的列表理解工作,但掃描「錯誤:」字符串兩次。由於它只是重新掃描實際的錯誤行,所以它工作正常,但它讓我很煩惱,我無法弄清楚如何使用單個掃描。這裏的工作代碼:

errors = [e[e.find('error:'):] for e in err.splitlines() if 'error:' in e] 

簡化明顯的(和錯誤的)方法是拯救「找到」的結果

errors = [e[i:] for i in e.find('error:') if i != -1 for e in err.splitlines()] 

不過,我得到「UnboundLocalError:局部變量‘E’之前引用分配」。盲目地顛倒理解中的'for'也是失敗的。這是如何完成的?

THanks。肯特

+0

提供一個樣本?首先是 – MattH

+2

。爲什麼不經常循環看起來像這樣可愛的東西? –

+0

'errors = filter(None,(e.split('error:',1)+ [None])[1] for err.splitlines())' – astynax

回答

3

您可以將檢查'error'發電機表達式中:

[e[i:] for i,e in 
((e.find('error:'),e) for e in err.splitlines()) 
if i != -1] 

你做什麼是創建一個嵌套的理解,並通過第二循環前使用e變量,你得到了UnboundLocalError

順便說一句,你還可以使用正則表達式和避免這種理解:

re.findall('error:(.*)', err) 

無需SPL它也行。

爲完整的錯誤(與error:部分)這工作:

re.findall('error:.*', err) 
+0

這可行,但看起來不太容易只需編寫一個生成器函數。 – Marcin

+0

@Marcin我正在糾正理解。真正的答案是簡單的正則表達式,比發生器更好。 – JBernardo

+0

我已經嘗試了第一種解決方案,在我的例子中它不會工作。只有最後一行的子字符串,而不是真正的錯誤消息...我添加了我的固定版本作爲評論不會接受代碼... – bcelary

2

使用一臺發電機在普通的循環來執行這種任務的其中需要狀態:

def errsplit(err): 
    for e in err.splitlines(): 
     errindex = e.find('error:') 
     if errindex > -1: yield e[errindex:] 

如果您需要這個列表,只需要做list(errsplit(err))

列表解析並不是真正用於處理存儲狀態,並且嘗試在其中使用存儲狀態會變得笨重。

這就是說,請注意,正如@JBernardo所建議的那樣,正則表達式可能會更好。

+2

+1爲了提高可讀性 – bcelary

0

我已經試過JBernardo的解決方案,但真正爲我工作是:

[errstr[i:] for i,errstr in 
((e.find('error:'), e) for e in err.splitlines()) 
if i != -1] 
+1

爲什麼堅持使用這種在一條線上不能放入並且複雜的閱讀器? – Marcin

+0

我只修復了JBernardo提供的其他版本,它實際上並不工作;) – bcelary