Самое подробное решение - не всегда самое нелегкое. Поэтому я добавляю небольшую модификацию (чтобы сохранить некоторые избыточные логические оценки):
def only1(l):
true_found = False
for v in l:
if v:
if true_found:
return False
else:
true_found = True
return true_found
Вот несколько таймингов для сравнения:
from itertools import ifilter, islice
def 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
return true_found
def DavidRobinson(l):
return l.count(True) == 1
def FJ(l):
return len(list(islice(ifilter(None, l), 2))) == 1
def 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:
return False
else:
true_found = True
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 значительно лучше, чем большинство других решений, размещенных здесь. Как и ожидалось, лучшие - это те, которые имеют поведение короткого замыкания, особенно решение, опубликованное Джоном Клементсом. По крайней мере, в случае двух ранних 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, и особенно подход Джона Клементса, снова оказались явно лучше.