根据一组值检查相等性

时间:2018-08-03 07:55:07

标签: python equality

假设我要检查一个变量是否等于几个值之一。我应该使用以下哪个表达式?

const ifelse = condition => a => b => condition ? a : b();
const factorial = n => ifelse(n == 0)(1)(() => n * factorial(n - 1));
//                                       ^^^^^
console.log(factorial(5));

编辑:从答案/评论中,我了解到:

  • 最不推荐使用第一个变体,其他变体同样被视为“ pythonic”。
  • 在短时间内,检查成员资格方面的性能差异可以忽略不计。元组的创建成本最低,集需要计算哈希。
  • 在某些极端情况下,这四个变体并不相同:
    • if s == 'one' or s == 'two' or s == 'three': pass if s in ('one', 'two', 'three'): pass if s in ['one', 'two', 'three']: pass if s in {'one', 'two', 'three'}: pass 运算符检查身份和相等性。
    • 逻辑in短路。我怀疑元组和列表的成员资格测试应按顺序进行评估,因此也会被短路。
    • 集合需要可散列的元素。

4 个答案:

答案 0 :(得分:1)

我认为以下三个是最好的:

if s in ('one', 'two', 'three'):
    pass

if s in ['one', 'two', 'three']:
    pass

if s in {'one', 'two', 'three'}:
    pass

但也许仍然是

if s in {'one', 'two', 'three'}:
    pass

仍然是最好的

计时

%timeit if 'one' in ('one', 'two', 'three'):pass

输出:

The slowest run took 21.60 times longer than the fastest. This could mean 
that an intermediate result is being cached.
10000000 loops, best of 3: 63.4 ns per loop

%timeit if 'one' in ['one', 'two', 'three']:pass

输出:

 10000000 loops, best of 3: 50.7 ns per loop

%timeit if 'one' in {'one', 'two', 'three'}:pass

输出:

10000000 loops, best of 3: 50.3 ns per loop

最后我更喜欢set{}),因为它是最快的

并且元组是最慢的,它是我最不喜欢的(在元组,列表和集合中)

答案 1 :(得分:1)

可以检查三个值,没关系。

第一个if s == 'one' or s == 'two' or s == 'three':可以说是Python程度较低的。在其中一个值比另一个值更有可能的情况下,它可能很方便。在这种情况下,您可以通过将最可能的值放在最前面来利用惰性计算,从而避免了大部分时间对整个表达式进行计算。

使用集合if s in {'one', 'two', 'three'}:会产生创建集合O(n)哈希的费用,但是如果要检查的变量很多,多次或者集合包含很多重复。

其他两个基本相同。我稍微偏爱一个不可变的元组,而不是一个列表,但这是出于与问题没有直接关系的原因。

在3个值的情况下对性能差异进行计时是没有用的。

答案 2 :(得分:1)

如果要重复多次或必须处理许多替代方法,则应使用set

但是,如果只使用一次,建议使用tuples

在任何情况下都不建议使用第一种类型。

答案 3 :(得分:0)

您可以使用您建议的任何选项,尽管第一个选项可能不太方便使用。

就性能而言,使用set的最后一个选项应该是最有效的,但这实际上取决于您的收藏集有多长时间。

如果您的收藏集中没有成千上万的条目,只需使用一个列表,该列表在任何用法下都会更常见,更灵活。