2016-11-22 2 views
7

私はFalse要素でいっぱいのリストから始めます。
これらの要素は、反復の過程で独立してTrueに切り替えられます。
リストが完全に真であることを知る必要があります。python一度にさまざまな等価性をチェックする最低コスト

その後、私のような繰り返しでそれらをチェックし、彼らが

[False, False, False] 

として起動、のは、私は3つの要素を持っているとしましょう:

elements == [True, True, True] 

要素のリストが固定されており、成長(または縮小してはなりません)。これらの要素はスイッチと考えることができ、入力によっていくつのものがあるかが決まり、それらはすべてスイッチオフされます。時間が経つにつれて起こる唯一の事は、反復で起こっているイベントによって個々のスイッチがオン(True)になることです。

pythonはどのようにチェックを行い、コストはいくらですか?
これを確認するためのコストの観点からは、どのような方法が最適ですか?
ビット操作の方法や、すべての要素を一度にチェックする方法はありますか?

+4

'true'を値の**数**してください? –

+1

@StefanPochmannこれを回答として投稿することができます。 OPの場合、これは「すべて」を示唆する答えよりも優れています。 –

+0

Pythonは 'all'と' any'組み込み関数を持っています、 'all'はすべての要素が' True'と評価されれば 'True'を返し、' any'は少なくとも一つの要素が 'True' – ettanany

答えて

2

ビット演算を使用して、フラグビットの配列として数値を使用できます。これを有効にするには、Trueをクリアビットとしてエンコードする必要がありますが、Falseをセットビットとしてエンコードする必要があります。この方法では、すべてのビットがクリアされた場合にのみ数値がゼロになります。

これは、フラグの数が固定されているためうまく動作します。セットされたビットの配列から始めれば、番号がゼロになるまでクリアするだけで済みます。

これは、ビットをクリアする際のわずかな複雑さとコストのために、はるかに高速な条件チェックを行います。数字が0であるかどうかのテストは、ブール値のリストにallを適用するよりもはるかに安いです。

質問に関するコメントは、カウントとリストを維持することを提案しました。値の1つが真になると、カウントはリストの長さの最終値になるか、リストの長さからゼロになります。それはうまくいくでしょうが、同じ事実がカウントとして1回2回、Truesの数として1回エンコードされるので、冗長です。

これは、カウントとリストを組み合わせたものです。冗長性はありません。

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と全て(l)'が空リストの場合の処理​​を行う場合 –

+0

私は自分のコメントをあまりにも賢いものとして削除しました。離散数学の授業では、多くの学生が空虚な言葉の発想に苦しんでいることを教えています。 –

+0

@JohnColeman、thx。実際、 'all([])'が 'true'を' 1'に等しい 'True'を返す理由は、実際には分かりません。 – SparkAndShine

3

@StefanPochmannのアイデアを実装し、設定されているフラグの数を追跡する独自のフラグクラスを作成できます。コンセプトの

証明:

import random 

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

print(i,f.flags()) 

典型的な出力:のようにテストされた

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 

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

'f.all()'ではなかろうか?ちょうど例えばnumpy配列のように。いい使用例、btw。 (私はほとんど同じだと思っていましたが、単に "on"アクションのみを考えました) –

+0

@StefanPochmann 'f.all()'はうまく聞こえるし、実装するのには簡単です。ほとんどの概念実証を意味していたので(例えば、完全に使用可能になる前に、 '__str__'のようなものはもちろん、いくつかのエラートラップが追加されているはずです)、OPに実装するためにOPに残しておきますこのルート。 –

関連する問題