【问题标题】:Python assert all elements in list is not none [duplicate]Python断言列表中的所有元素不是没有[重复]
【发布时间】:2021-11-03 04:55:03
【问题描述】:

我想知道我们是否可以断言列表中的所有元素都不是None,因此a = None 会引发错误。

样本列表为[a, b, c]

我已经尝试过assert [a, b, c] is not None,如果任何一个元素不是None,它会返回True,但没有验证全部。你能帮忙弄清楚吗?谢谢!!

【问题讨论】:

  • assert [a, b, c] is not None 将通过即使所有元素都是Noneis None唯一是...Noneis 表示同一个对象,而不是相等性检查。也无法创建更多 None 类型的实例。
  • "assert [a, b, c] 不是None,如果任何一个元素不是None,则返回True" no。这不是正在发生的事情,它正在对None 进行身份检查。任何列表都不是None,其实任何对象除了None都不是None。

标签: python assert


【解决方案1】:

性能介于not inall 之间。请注意,对于这种特殊情况,带有 all 的明智(首选)版本最终会执行缓慢 - 但至少比 min 领先

def assert_all_not_none(l):
    for x in l:
        if x is None:
            return False
    return True

编辑:这里有一些基准供有兴趣的人参考

from timeit import timeit


def all_not_none(l):
    for b in l:
        if b is None:
            return False
    return True


def with_min(l):
    min(l, key=lambda x: x is not None, default=False)


def not_in(l):
    return None not in l


def all1(l):
    return all(i is not None for i in l)


def all2(l):
    return all(False for i in l if i is None)


def all_truthy(l):
    return all(l)


def any1(l):
    return any(True for x in l if x is None)


l = ['a', 'b', 'c'] * 20_000

n = 1_000

# 0.63
print(timeit("all_not_none(l)", globals=globals(), number=n))

# 3.41
print(timeit("with_min(l)", globals=globals(), number=n))

# 1.66
print(timeit('all1(l)', globals=globals(), number=n))

# 0.63
print(timeit('all2(l)', globals=globals(), number=n))

# 0.63
print(timeit('any1(l)', globals=globals(), number=n))

# 0.26
print(timeit('all_truthy(l)', globals=globals(), number=n))

# 0.53
print(timeit('not_in(l)', globals=globals(), number=n))

出乎意料的获胜者:all(list)因此,如果您确定列表不会包含空字符串或零等虚假值,那么这样做没有错。

【讨论】:

  • 这些说法真的让我渴望看到一个基准:-)
  • 是的,刚刚添加了一些快速而肮脏的列表,并有足够长的列表进行测试
  • 我认为这有点误导,因为除了all_not_none 之外的所有内容通常都会在没有额外函数调用的情况下内联使用(如if any(l):),而all_not_none 与电话一起使用(如if all_not_none(l))。但没关系。也可以包括我在评论中提到的all(False ...),应该更快,原因与this相同。
  • 哇,这是一个巨大的差异。我为all 添加了另一个测试,它确实快得多。不错的收获:)
  • any 应该是 not any
【解决方案2】:

你的意思是all:

>>> assert all(i is not None for i in ['a', 'b', 'c'])
>>>

或者简单地说:

assert None not in ['a', 'b', 'c']

P.S 刚刚注意到@don'ttalkjustcode 添加了上述内容。

或者min:

>>> assert min(a, key=lambda x: x is not None, default=False)
>>>

【讨论】:

  • default 应该是True,尽管我觉得min 对此很奇怪。例如,即使没有 None,它也会为 [0, 1, 2] 发出 AssertionError。顺便说一句,我认为您之前尝试过的正确更快的all(...) 确实更快,请参阅@rv 的基准。
【解决方案3】:

除非你有一个奇怪的元素声称它等于None

assert None not in [a, b, c]

【讨论】:

  • 赞,因为这个版本似乎也是最快的。如果有人好奇,比all 快大约 5 倍,并检查每个元素是否不是None,但在性能方面非常接近all([a, b, c])
  • @rv.kvetch all([a, b, c]) 的安全性明显较低,因为任何错误值(例如零)都会返回 False
  • 是的,我从来没有说过它是完美的;但不知何故,它的性能比带有显式None 检查的那个要好得多,相比之下这似乎很慢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 2018-10-01
  • 2020-06-25
  • 2018-03-03
  • 2018-05-15
  • 2013-06-01
  • 1970-01-01
相关资源
最近更新 更多