你似乎對混爲一談循環for
的語法(一個陳述,後面跟着一套陳述......也就是所謂的「代碼塊」)和一個列表理解(一個表達式)。
這裏有一個列表理解:
#!/usr/bin/python
# Given:
b = [1,2,3,'vv']
a = [int(x) for x in b]
...這是語法上有效。但是,該示例的語義會引發異常,因爲'vv'不是有效的文字(字符串)。它不能被解釋爲一個十進制整數。
這裏有一個for
循環:
#!/usr/bin/python
# Given:
b = [1,2,3,'vv']
a = list()
for x in b:
try:
a.append(int(x))
except ValueError:
pass
在這種情況下,我們明確地循環在給定的列表(b
),而忽略升起時,我們try
每個這些條目的轉換爲整數任何ValueError
例外。
沒有合理的方法來處理列表理解中的異常。您可以編寫一個函數,以便爲任何無效輸入值返回一些標記值(來自表達式)。這看起來像這樣:
#/usr/bin/python
# Given:
b = [1, 2, 3, 'vv']
def mk_integer_if_possible(n):
'''Returns an integer or the sentinel value None
'''
results = None
try:
results = int(n)
except ValueError:
pass
return results
# Use that function:
a = [mk_integer_if_possible(x) for x in b if mk_integer_if_possible(x) is not None]
注:荒謬的函數名是故意的。這是一個醜陋的方式來做到這一點,並且對b
的每個元素不得不稱呼這個假定函數TWICE的尷尬表明你不應該使用列表理解來解決這種情況。 (你必須調用它來進行一次轉換,但是再次調用該條件。保存一次調用的結果當然是一個STATEMENT,我們不能在EXPRESSION中嵌入它)。
語句包含一個或多個表達式。表達式是語句的組成部分。 Python嚴格描述語句和表達式。賦值是Python中的語句。這些區別可以細微差別,還有其他編程語言,其中賦值是表達式,而不是由語言的語法嚴格定義爲語句。
因此,無論何時需要處理可能的異常,並且迭代任何類型的數據集,並且通常需要過濾通過在列表理解上映射函數生成的結果時,請使用for
循環。
順便說一句,在這個例子中需要明確使用表達式is not None
。如果我試圖用Python的隱式布爾處理簡化if mk_integer_if_possible(x)
的測試,那麼我們會無意中過濾出b
中任何計算爲整數0的條目以及任何通過我不明智的函數返回的作爲None
哨兵的條目。
在Python中,使用隱式布爾值作爲條件通常很好。 None
和False
以及任何數值爲零的值,任何空字符串或任何類型的空列表,元組或字典在布爾上下文中都被視爲「假」。但是,在處理標記值時,最好使用is
運算符並明確測試對象標識。否則,您會遇到一些情況,您的情況可能會與您的哨兵以外的值相匹配。 (方便的技巧:如果你曾經遇到需要允許None
通過某種過濾器或傳遞它,但你需要一些其他的哨兵...只需使用sentinel = object()
...你可以創建(實例化)一個通用Python object
和使用is
來匹配你的標記處理。這將是唯一的代碼和沒有其他Python對象或類型將匹配它。保證)。
順便說一下...我應該注意到,這個代碼在技術上不是「從列表中提取數字」。它將返回列表中所有可以轉換的條目的整數。這是一個挑逗;但任何優秀工程師都會注意到這一點。你想從輸入列表中返回所有整數嗎?還是你想要返回所有條目作爲整數,如果可以這樣轉換?你的代碼表明你試圖完成後者;所以這就是我爲你實施我的工作例子的過程。然而,實施後的語義,你可能會想用(數學)加法或乘法的身份屬性,像這樣:
# ... from within some function:
try:
results = x == x + 0 # Additive identity
except (TypeError, ValueError):
results = None
return results
它沒有工作.... – lovemysql 2014-09-13 11:28:52
ValueError異常:無效的字面INT()與基地10:'vv' – lovemysql 2014-09-13 11:29:32
現在這個工作..你可以告訴我爲什麼拳頭選項沒有工作 – lovemysql 2014-09-13 11:33:43