2016-11-22 47 views
7

我從一個充滿False元素的列表開始。
然後那些元素在迭代過程中獨立地切換到True
我需要知道列表何時完全爲True。蟒蛇一次檢查各種平等的最低成本

比方說,我有3個要素,他們開始爲

[False, False, False] 

然後我檢查他們在諸如迭代:

elements == [True, True, True] 

元素的列表是固定的,不應該增加(或縮小)。您可以將這些元素視爲開關,輸入決定了這些元素的數量,並開始關閉所有元素。隨着時間的推移,唯一可能發生的事情是單個開關被迭代中發生的事件打開(True)。

python如何做檢查和成本是多少?
檢查成本方面最好的方法是什麼?
是否有位操作或任何一次檢查所有元素的方法?

+4

保持TRUE;值的** **算? –

+1

@StefanPochmann你可以發表這個答案。在OP的情況下,這比提出「全部」的答案要好。 –

+0

Python具有'all'和'any'內建函數,'all'如果所有元素被評估爲'True'則返回'True',如果至少有一個元素評估爲'True'則'any'返回'True'。 – ettanany

回答

2

您可以使用位操作將數字用作標誌位數組。爲了實現這個功能,我們必須將您的True編碼爲一個清零位,但將False編碼爲一個位。這樣,如果所有位都被清除,數字只會變爲零。

這很好用,因爲標誌的數量是固定的。通過從一組數位開始,您只需清除它們,直到數字變爲零。

這樣做的交易速度要快得多,條件檢查的位稍微複雜一些,成本也很高。測試一個數字是否爲零比在布爾表的任何列表上應用all便宜得多。

對問題的評論建議保持計數和列表。當其中一個值變爲真時,計數或者上升到列表長度的最終值或者從列表長度下降到零。這將工作,但它是多餘的,因爲相同的事實編碼兩次一次作爲計數,一次編碼爲Trues數量。

這結合了計數和列表。它不包含冗餘。

與5集位開始時:

>>> bin((1<<5)-1) 
'0b11111' 

然後清除它們。這將清除第4位:

>>> bin(((1<<5)-1) & ~(1 << 3)) 
'0b10111' 

這將使你的循環有一個條件,如下面的循環:

flags = (1<<5)-1 
n = 0 
while flags: 
    flags &= ~(1<<n) 
    print bin(flags) 
    n += 1 

該環路與5位集開始,並清除他們一次一個。

>>> flags = (1<<5)-1 
>>> n = 0 
>>> while flags: 
... flags &= ~(1<<n) 
... print bin(flags) 
... n += 1 
... 
0b11110 
0b11100 
0b11000 
0b10000 
0b0 
+0

*「您無法從計數中判斷出哪些條件已被觸發」* - 但您可以從列表中知道。它沒有更少的調試能力。 –

+0

它指的是建議的計數。不在列表中。現在,如果建議是保持一個計數和列表。這也可以,但僅靠伯爵不會。 –

+0

*是*建議。如果沒有列表,則沒有「真」值要計算。 (我懷疑沒有列表可以更新計數。) –

4

使用all

>>> l = [True, True, True] 
>>> all(l) 
True 

要注意,如果迭代是空的,它會返回True爲好。

>>> all([]) 
True 
+0

'如果我和所有(l)'都會爲空列表案例工作 –

+0

我刪除了我的評論,因爲它太過於迂腐。通過教授離散數學課程中的量詞,我知道很多學生確實在與真實的陳述相提並論。 –

+0

@JohnColeman,thx。實際上,我不明白爲什麼all([])'返回'True',因爲'int(True)'等於'1'。 – SparkAndShine

3

您可以創建自己的標誌類,它實現@StefanPochmann的想法並跟蹤已設置了多少標誌。

概念證明:

class flags: 
    def __init__(self,n): 
     self.__flags = [False]*n 
     self.__ntrue = 0 

    def flags(self): 
     return self.__flags[:] #so read only 

    def __len__(self): 
     return len(self.__flags) 

    def check(self,i): 
     return self.__flags[i] 

    def on(self,i): 
     if not self.check(i): 
      self.__ntrue +=1 
      self.__flags[i] = True 

    def off(self,i): 
     if self.check(i): 
      self.__ntrue -=1 
      self.__flags[i] = False 

    def toggle(self,i): 
     if self.check(i): 
      self.off(i) 
     else: 
      self.on(i) 

    def ntrue(self): 
     return self.__ntrue 

測試,如:

import random 

i = 0 
f = flags(5) 
while f.ntrue() != len(f): 
    i +=1 
    f.toggle(random.randint(0,4)) 

print(i,f.flags()) 

典型輸出:

19 [True, True, True, True, True] 
+0

'while not f.all()'怎麼樣?就像例如numpy數組一樣。很好的例子用法,順便說一句。 (我曾經想過幾乎相同,只是只有「開」動作。) –

+0

@StefanPochmann'f.all()'聽起來不錯,而且很容易實現。由於它主要是作爲概念證明(例如,它應該添加一些錯誤陷阱,在它變得完全可用之前不要提及像__str__這樣的東西),我將把它留給OP來實現,如果他們想要去這條路線。 –