如何检查列表是否只有一个真值? [英] How can I check that a list has one and only one truthy value?

查看:62
本文介绍了如何检查列表是否只有一个真值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在python中,我有一个列表,它应该有一个且只有一个真值(即,bool(value) is True).有没有聪明的方法来检查这个?现在,我只是遍历列表并手动检查:

In python, I have a list that should have one and only one truthy value (that is, bool(value) is True). Is there a clever way to check for this? Right now, I am just iterating across the list and manually checking:

def only1(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_found

这看起来很不雅观,而且不是很像 Pythonic.有没有更聪明的方法来做到这一点?

This seems inelegant and not very pythonic. Is there a cleverer way to do this?

推荐答案

最冗长的解决方案并不总是最不雅观的解决方案.因此我只添加了一个小的修改(为了保存一些冗余的布尔评估):

The most verbose solution is not always the most unelegant solution. Therefore I add just a minor modification (in order to save some redundant boolean evaluations):

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

<小时>

以下是一些比较时间:


Here are some timings for comparison:

# file: test.py
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 #"Too Many Trues"
    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:
                # 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 值的情况.

As can be seen, the OP solution is significantly better than most other solutions posted here. As expected, the best ones are those with short circuit behavior, especially that solution posted by Jon Clements. At least for the case of two early True values in a long list.

这里完全没有 True 值也一样:

Here the same for no True value at all:

$ 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

我没有检查统计显着性,但有趣的是,这一次 F.J. 建议的方法,尤其是 Jon Clements 建议的方法似乎明显更胜一筹.

I did not check the statistical significance, but interestingly, this time the approaches suggested by F.J. and especially that one by Jon Clements again appear to be clearly superior.

这篇关于如何检查列表是否只有一个真值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆