TL;博士
據我所知,all
是更好,當你可能會比較布爾語句的變化量,並使用and
是多大一有限布爾陳述更好,並採用all
時使用,嘗試使用生成器函數。
詳細
編輯解釋(用於使用術語短挑錯推薦打印的清楚) 及其在有限語句使用是優選的,因爲Python
將短路每個布爾語句一旦真相的評價可以確定。 請參閱答案的結尾處以獲取證明和詳細示例。
由於由連續and
報表的任何聲明將False
如果至少有一個說法是False
那麼編譯器只知道檢查,直到它到達一個虛假的答案:
status1 == 100 and status2 == 300 and status3 == 400
它會檢查status1 == 100
如果這被發現是False
,它會馬上停止處理該陳述,如果它是True
如果現在檢查status2 == 300
等
這種邏輯可以直觀使用循環論證:
圖片我們寫的和聲明的行爲,你會檢查每個語句沿線,並確定是否所有的人都True
並返回True
或者我們會找到一個False
值並返回False
。您可以在達到第一個虛假陳述後節省時間,並立即退出。
def and(statements):
for statement in statements:
if not statement:
return False
return True
和or
我們會寫會盡快爲True
語句中找到退出,因爲這證明全部或語句是不相關的報表的總體列真理作爲一個整體邏輯:
def or(statements):
for statement in statements:
if statement:
return True
return False
該邏輯,當然混合並適當地交織在一起服從操作的順序的時and
和or
語句混合在一起
的and
和any
聲明有助於避免出現這種情況:
collection_of_numbers = [100,200,300,400,500,600,.....]
if collection_of_numbers[0] == 100 and collection_of_numbers[1] == 200 and .......:
print "All these numbers make up a linear set with slope 100"
else:
print "There was a break in the pattern!!!"
與
or
collection_of_numbers = [100,200,300,400,500,600,.....]
if collection_of_numbers[0] == 100 or collection_of_numbers[1] == 200 or .......:
print "One of these numbers was a multiple of 100"
else:
print "None of these numbers were multiples of 100"
例如
同理:
temp = []
itr = 0
for i in collection_of_numbers:
temp.append(i == itr)
itr += 100
if all(temp):
print "The numbers in our collection represent a linear set with slope 100"
else:
print "The numbers in out collection do not represent a linear set with slope 100"
的一種愚蠢的例子,但我認爲這體現了類型當all
可能有些用處時。
類似的說法是對任何提出:
temp = []
for i in collection_of_numbers:
temp.append(i%3 == 0)
if any(temp):
print "There was at least one number in our collect that was divisible by three"
else:
print "There were no numbers in our collection divisible by three"
雖然可以說,您將節省更多的時間執行使用循環這樣的邏輯。
爲and
,而不是all
:
itr = 0
result = True
for i in collection_of_numbers:
if not i == itr:
result = False
break
itr += 100
if result:
print "The numbers in our collection represent a linear set with slope 100"
else:
print "The numbers in out collection do not represent a linear set with slope 100"
的區別是這個檢查每一個條目,節約了大量的大型成套時間,其中一個初入門傷了你的條件之前,將打破。
爲or
,而不是any
:
temp = []
result = False
for i in collection_of_numbers:
if i%3 == 0:
result = True
break
if result:
print "There was at least one number in our collect that was divisible by three"
else:
print "There were no numbers in our collection divisible by three"
這將檢查,直到它找到一個滿足的條件爲以後什麼都不會改變說法如何True
是。
**編輯**上面使用短路短語和聲明證明的示例。 考慮
1 == 2 and 2 == 2
和
all([1 == 2, 2 == 2])
第一條語句將評估1 == 2
是False
和作爲一個整體的語句將immeadiately短路並evaulated到False
。鑑於第二個陳述將評估1 == 2
爲False
,2 == 2
爲True
,則在進入功能and
時,它現在將返回False
。必須首先評估每條語句的額外步驟是爲什麼如果您正在檢查一些小型案例的有限布爾檢查以便不使用該函數,那麼這是更好的辦法。
雖然對於兩條語句無關緊要,但如果您舉一個極端例子,您會看到我對所有布爾語句的評估是短路的。下面的測試以不同的方式評估1000
布爾語句,並以它們的執行時間爲單位。每條語句的第一個布爾語句將會在整個布爾語句上導致短路,但不會在評估上產生短路。
test.py
import timeit
explicit_and_test = "1 == 0 and " + " and ".join(str(i) + " == " + str(i) for i in range(1000))
t = timeit.Timer(explicit_and_test)
print t.timeit()
function_and_test = "all([1 == 0, " + ", ".join(str(i) + " == " + str(i) for i in range(1000)) + "])"
t = timeit.Timer(function_and_test)
print t.timeit()
setup = """def test_gen(n):
yield 1 == 0
for i in xrange(1,n):
yield i == i"""
generator_and_test = "all(i for i in test_gen(1000))"
t = timeit.Timer(generator_and_test,setup=setup)
print t.timeit()
當運行:
$ python test.py
0.0311999320984 # explicit and statement
26.3016459942 # List of statements using all()
0.795602083206 # Generator using all()
報表的短路評價的影響是顯而易見這裏由過高的因素。你可以看到,即使對於任何有限的布爾語句來說,最好的方法都是使用一個明確的語句,正如我在冗長的答案的開頭所述。這些函數適用於您可能不知道需要評估多少個布爾語句的情況。
如果你做'all([status1 == 100,status2 == 300,status3 = 400]),它首先必須創建整個列表,所以我猜'和'是更好的。雖然可能與發電機不同。 –
您可以['timeit'](http://docs.python.org/2/library/timeit.html)確定,但我認爲使用邏輯運算符總是比使用邏輯運算符更快,而不是構建新的列表對象並調用一個函數。 – 2rs2ts