我从一个充满False
元素的列表开始
然后在迭代过程中将这些元素独立切换到True
我需要知道列表何时完全为True。
假设我有3个元素,它们以
开头[False, False, False]
然后我在迭代中检查它们:
elements == [True, True, True]
元素列表是固定的,不应增长(或缩小)。您可以将这些元素视为开关,输入决定了它们的数量,并且它们开始全部关闭。随着时间的推移,唯一可能发生的事情是,迭代中发生的事件会打开(True)各个开关。
python如何进行检查以及成本是多少?
检查成本的最佳方法是什么?
有没有一种方法可以使用位操作或同时检查所有元素的任何方法?
答案 0 :(得分:4)
答案 1 :(得分: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]
答案 2 :(得分:2)
您可以使用位操作将数字用作标志位数组。为了实现这一点,我们必须将True
编码为清除位,但将False
编码为设置位。这样,如果清除所有位,则该数字仅变为零。
这很好用,因为标志的数量是固定的。通过从一组设置位开始,您只需清除它们,直到数字变为零。
这使得条件检查的速度更快,因为清除这些位会带来更多的复杂性和成本。测试数字是否为零比将all
应用于任何布尔值列表要便宜得多。
对该问题的评论建议保留计数和清单。当其中一个值变为真时,计数或者上升到列表长度的最终值,或者从列表的长度下降到零。这可行,但它是多余的,因为相同的事实被编码两次作为计数,一次编码为真人数。
这结合了计数和列表。它不包含冗余。
从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