python一次性检查各种等式的最低成本

时间:2016-11-22 19:43:52

标签: python list

我从一个充满False元素的列表开始 然后在迭代过程中将这些元素独立切换到True 我需要知道列表何时完全为True。

假设我有3个元素,它们以

开头
[False, False, False]

然后我在迭代中检查它们:

elements == [True, True, True]

元素列表是固定的,不应增长(或缩小)。您可以将这些元素视为开关,输入决定了它们的数量,并且它们开始全部关闭。随着时间的推移,唯一可能发生的事情是,迭代中发生的事件会打开(True)各个开关。

python如何进行检查以及成本是多少? 检查成本的最佳方法是什么?
有没有一种方法可以使用位操作或同时检查所有元素的任何方法?

3 个答案:

答案 0 :(得分:4)

使用all

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

请注意,如果iterable为空,它也将返回True

>>> all([])
True

答案 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