[英]Is OR and ELSE similar in list comprehension statement
請幫助我理解為什么這樣。 下面的代碼以迭代方式列出重復項。 但是,在if..else語句中使用or運算符的行為類似於else。
j = set()
my_list = [1, 2, 3 ,3 , 3 ,4, 4]
j_add = j.add
twice = set(x for x in my_list if x in j or j_add(x))
print list(twice)
期望這行是:
twice = set(x for x in my_list if x in j else j_add(x))
認為或返回布爾值而不是值
or
運算符返回最后一個求值的參數,該參數可以是布爾值,也可以不是布爾值。
在文檔中解釋了此行為:
請注意,
and
和or
限制值和類型都不會返回False
和True
,而是返回最后一個求值的參數。 有時這很有用,例如,如果s
是一個字符串,如果為空則應替換為默認值,則表達式s or 'foo'
產生所需的值。
當然,它有助於記住什么被解釋為false和什么被解釋為true:
以下值被解釋為false:
False
,None
,所有類型的數字零,空字符串和容器(包括字符串,元組,列表,字典,集合和Frozensets)。 所有其他值均解釋為true。
所以在表達式中:
A = B or C
正如@MartijnPieters在評論中指出的那樣, or
表達式短路。 如果第一個參數(在這種情況下為B
)被解釋為true,則整個表達式必須為true,因此永遠不會對第二個參數( C
)求值。 因此,第一個參數( B
)是“最后計算的參數”,它是返回的結果。 但是,如果將第一個參數( B
)解釋為false,則仍必須對第二個參數( C
)求值以確定表達式的真實性(不會發生短路)。 在這種情況下,“最后計算的參數”是第二個參數( C
),無論表達式計算的是true還是false都將返回該第二個參數。
它有效地完成了與條件表達式相同的操作:
A = B if B else C
但是,條件表達式僅在版本2.5中添加到Python,而布爾運算符的行為從一開始就存在(或至少存在很長時間)。 大多數經驗豐富的Python程序員將很容易認識並養成使用A = B or C
的習慣。 條件表達式通常保留給更復雜的條件使用,而這些條件不適用於簡單的or
(例如,在A = B if X else C
則條件不是基於B
的真實性而是X
,這可以是簡單值的任何形式到一個復雜的表達式)。
但是,您需要注意,因為正如JaredGoguen在他的答案中指出的那樣,將OP示例中的or
更改為else
實際上會改變代碼的行為。 該代碼的編寫取決於or
運算符的這種特定行為。 您不能只用條件表達式替換對or
任何使用。 也可能需要其他重構。
我可能會在這里做出值判斷,並說這不是好代碼,因為它使用了的短路行為or
產生了副作用。
考慮給定的條件: if x in j or j_add(x)
。
當x in j
, or
短路,則跳過條件的j_add(x)
部分,並求值為True
。
當x not in j
,檢查語句j_add(x)
的真實性。 此方法返回None
,它是虛假的,所以or
求值為False
。
因此,整個條件將與x in j
相同。 但是j_add(x)
具有將x
加到j
的副作用。 為了利用唯一的成員my_list
快速而全面地理解該副作用,正在利用該副作用。
將or
else
更改為else
仍將根據需要構造j
,但是會不恰當地將None
, j_add(x)
的返回值, j_add(x)
到twice
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.