Найбільш багатослівне рішення - не завжди найелегантніше рішення. Тому я додаю лише незначну модифікацію (з метою збереження надлишкових булевих оцінок):
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, і особливо той, що Йон Клементс, знову видаються явно вищими.