最冗长的解决方案并不总是最简单的解决方案。因此,我仅添加了一个较小的修改(以节省一些冗余的布尔值评估):
def only1(l): true_found = False for v in l: if v: # a True was found! if true_found: # found too many True's return False else: # found the first True true_found = True # found zero or one True value return true_found
以下是一些比较时间:
# file: test.pyfrom itertools import ifilter, islicedef OP(l): true_found = False for v in l: if v and not true_found: true_found=True elif v and true_found: return False #"Too Many Trues" return true_founddef DavidRobinson(l): return l.count(True) == 1def FJ(l): return len(list(islice(ifilter(None, l), 2))) == 1def JonClements(iterable): i = iter(iterable) return any(i) and not any(i)def moooeeeep(l): true_found = False for v in l: if v: if true_found: # found too many True's return False else: # found the first True true_found = True # found zero or one True value return true_found
我的输出:
$ python -mtimeit -s 'import test; l=[True]*100000' 'test.OP(l)' 1000000 loops, best of 3: 0.523 usec per loop$ python -mtimeit -s 'import test; l=[True]*100000' 'test.DavidRobinson(l)' 1000 loops, best of 3: 516 usec per loop$ python -mtimeit -s 'import test; l=[True]*100000' 'test.FJ(l)' 100000 loops, best of 3: 2.31 usec per loop$ python -mtimeit -s 'import test; l=[True]*100000' 'test.JonClements(l)' 1000000 loops, best of 3: 0.446 usec per loop$ python -mtimeit -s 'import test; l=[True]*100000' 'test.moooeeeep(l)' 1000000 loops, best of 3: 0.449 usec per loop
可以看出,OP解决方案明显优于此处发布的大多数其他解决方案。不出所料,最好的是那些具有短路性能的产品,尤其是乔恩·克莱门茨(Jon
Clements)发布的解决方案。至少对于
True一长串中的两个早期值而言。
这里完全没有任何
True价值:
$ python -mtimeit -s 'import test; l=[False]*100000' 'test.OP(l)' 100 loops, best of 3: 4.26 msec per loop$ python -mtimeit -s 'import test; l=[False]*100000' 'test.DavidRobinson(l)' 100 loops, best of 3: 2.09 msec per loop$ python -mtimeit -s 'import test; l=[False]*100000' 'test.FJ(l)' 1000 loops, best of 3: 725 usec per loop$ python -mtimeit -s 'import test; l=[False]*100000' 'test.JonClements(l)' 1000 loops, best of 3: 617 usec per loop$ python -mtimeit -s 'import test; l=[False]*100000' 'test.moooeeeep(l)' 100 loops, best of 3: 1.85 msec per loop
我没有检查统计显着性,但是有趣的是,这一次FJ建议的方法,尤其是Jon Clements提出的方法似乎明显更好。



