以下是否有區別?Python 3 and-or vs if-else
print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')
以下是否有區別?Python 3 and-or vs if-else
print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')
實際上它們是相同的;在理論上它們是不同的,但只有當__bool__
方法都有副作用:
>>> class Weird:
state = False
def __bool__(self):
self.state = not self.state
return self.state
>>> x = Weird(); print(x if x else 'no x available')
<__main__.Weird object at 0x0000000003513160>
>>> x = Weird(); print(x and x or 'no x available')
no x available
如果碰上你有更嚴重的問題擔心這個理論情況。
還要注意的是:
>>> x = Weird(); print(x or 'no x available')
<__main__.Weird object at 0x00000000035071D0>
所以克拉斯伊萬的答案是技術上的錯誤。
底線,使用if
表達式,因爲它可以更清楚地表達您的意思。
這是我所希望的那種答案;他們如何行動的實際差異(我知道,我應該更清楚地詢問一下)。儘管謝謝你的回答! :) –
是啊!剛剛意識到這一點並回過頭來進行編輯,而且您已經證明了我想要添加的東西 - 唯一的區別是'__bool __(self)'方法不是「純函數」。 –
@KlassIvan我編輯了我的答案,使這一點更清晰。 – Duncan
兩條線都相同:
print(x or 'no x available')
關於第二替代: 始終牢記的是,根據操作者的優先級and
首先計算,所以它首先計算x and x
,這是完全無用的 - 它等於x
運行此:
import dis
def f1():
print(x if x else 'no x available')
def f2():
print(x and x or 'no x available')
def f3():
print(x or 'no x available')
dis.dis(f1)
dis.dis(f2)
dis.dis(f3)
我們得到,對於f1
:
4 0 LOAD_GLOBAL 0 (x)
3 POP_JUMP_IF_FALSE 12
6 LOAD_GLOBAL 0 (x)
9 JUMP_FORWARD 3 (to 15)
>> 12 LOAD_CONST 1 ('no x available')
>> 15 PRINT_ITEM
16 PRINT_NEWLINE
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
爲f2
:
7 0 LOAD_GLOBAL 0 (x)
3 POP_JUMP_IF_FALSE 12
6 LOAD_GLOBAL 0 (x)
9 JUMP_IF_TRUE_OR_POP 15
>> 12 LOAD_CONST 1 ('no x available')
>> 15 PRINT_ITEM
16 PRINT_NEWLINE
17 LOAD_CONST 0 (None)
20 RETURN_VALUE
對於來自@Klass伊萬採取f3
:
10 0 LOAD_GLOBAL 0 (x)
3 JUMP_IF_TRUE_OR_POP 9
6 LOAD_CONST 1 ('no x available')
>> 9 PRINT_ITEM
10 PRINT_NEWLINE
11 LOAD_CONST 0 (None)
14 RETURN_VALUE
所以f1
和f2
是不一樣的。正如克拉斯提到的,他們有不同的邏輯。 f3
和f1
版本也有所不同,即使邏輯上它們應該相當,f3
備用一些操作。
準確 - '9 JUMP_FORWARD'與'9 JUMP_IF_TRUE_OR_POP' - f1和f2不一樣。 –
@KlassIvan我注意到它並編輯它。不過,謝謝你指出。 – luk32
代碼方面,我認爲這已被涵蓋,但我會注意到,你在這裏做的是在語言上非常不同,並且可能對讀取你的代碼的人有非常不同的影響,也許只是那些潛意識瀏覽網站的前端(即使是通過參與或瞭解代碼的人也會發現自己在心理上受到潛在'符號鏈接'的影響*)。要進一步打破下來,讓我們考慮一個字符串值x
:
var x = "spoon";
print(x if x else 'no x available')
# compared to:
print(x and x or 'no x available')
它仍然很難看到究竟會發生什麼,「勺子」在這裏,所以讓事情更清晰,我們可以只需撥打我們的變量「hasSpoon」而不是給它分配一個字符串(但是如果你喜歡的話,你可以相信我們已經給它分配了一串「勺子」......):
print(hasSpoon if hasSpoon is true else 'no hasSpoon available')
# compared to:
print(hasSpoon and hasSpoon or 'no hasSpoon available')
正如我們所看到的,在一審的邏輯閱讀將是我們的隱喻餐具的持有者有一個勺子,如果他們有一個勺子,我想我們會在(和其他可能同意他們有沒有提供給他們的勺子的條件,而不是實際上有一個有點奇怪,但可能的勺子,但現在讓我們暫時擱置它。)
在第二個表達式中,邏輯蘊涵相反,我們的理論小餐館裏有一把勺子,還有一把勺子,這是一種重複的方式。因此,如果您想向任何潛在的代碼讀者以及任何可能受其代理人影響的人表達意見,那些有勺子的人很可能會有勺子,而那些沒有選擇沒有勺子,你會使用第一個選項。另一方面,如果你想表示某個人既有勺子又有勺子,或者他們有沒有向他們開放勺子的條件,你可以使用第二個表達式。
什麼的。
*我在這裏象徵性地使用術語,如果你會赦免雙關語。
區別在於第一個是可讀的。 –
/我正在等待某人使用[dis](https://docs.python.org/2/library/dis.html#module-dis)。 – luk32
等待,你忘了'['no x available',x] [bool(x)]'* ducks * – kojiro