检查列表中的所有元素是否相同

问题:

我需要以下功能:
 输入:a list
 产量

  •  True如果输入列表中的所有元素使用标准相等运算符求值彼此相等;
  •  False否则。

 性能:当然,我宁可不要不必要的开销。
我觉得最好:

  • 遍历列表
  • 比较相邻元素
  • AND所有生成的布尔值

但我不知道什么是最坚定的方法来做到这一点。
 编辑
感谢您的所有好的答案。我评了几个,真的很难选择@KennyTM和@Ivo van der Wijk解决方案。
缺乏短路功能只能在早期有不平等的元素的长输入(超过50个元素)上受到伤害。如果这种情况经常发生(通常取决于列表可能有多长时间),则需要短路。最好的短路算法似乎是@KennyTM checkEqual1。然而,它支付了很大的代价:

  • 高达20倍的性能几乎相同的列表
  • 在短名单上的性能高达2.5倍

如果具有早期不相等元素的长输入不发生(或很少发生),则不需要短路。那么,迄今为止最快的是@Ivo van der Wijk解决方案。

回答:

一般方法:

def checkEqual1(iterator):
    iterator = iter(iterator)
    try:
        first = next(iterator)
    except StopIteration:
        return True
    return all(first == rest for rest in iterator)

一内胆:

def checkEqual2(iterator):
   return len(set(iterator)) <= 1
&#91;/code&#93;
也是一线:
&#91;code lang="python"&#93;
def checkEqual3(lst):
   return lst&#91;1:&#93; == lst&#91;:-1&#93;
&#91;/code&#93;
3个版本之间的区别是:
<ol>
<li>在<code>checkEqual2</code>内容必须可以是哈希的。</li>
<li> <code>checkEqual1</code>和<code>checkEqual2</code>可以使用任何迭代器,但<code>checkEqual3</code>必须采用序列输入,通常是像列表或元组这样的具体容器。</li>
<li> 一旦发现差异,<code>checkEqual1</code>停止。</li>
<li>由于<code>checkEqual1</code>包含更多的Python代码,因此在开始时许多项目相同时效率较低。</li>
<li>由于<code>checkEqual2</code>和<code>checkEqual3</code>总是执行O(N)复制操作,所以如果您的大多数输入将返回False,它们将需要更长的时间。</li>
<li> <code>checkEqual2</code>和<code>checkEqual3</code>不能轻易更改为采用比较<code>a is b</code>而不是<code>a == b</code>。</li>
</ol>
 <code>timeit</code>结果,对于Python 2.7和(只有s1,s4,s7,s9应该返回True)

s1 = [1] * 5000
s2 = [1] * 4999 + [2]
s3 = [2] + [1]*4999
s4 = [set([9])] * 5000
s5 = [set([9])] * 4999 + [set([10])]
s6 = [set([10])] + [set([9])] * 4999
s7 = [1,1]
s8 = [1,2]
s9 = []

我们得到

      | checkEqual1 | checkEqual2 | checkEqual3  | checkEqualIvo | checkEqual6502 |
|-----|-------------|-------------|--------------|---------------|----------------|
| s1  | 1.19   msec | 348    usec | 183     usec | 51.6    usec  | 121     usec   |
| s2  | 1.17   msec | 376    usec | 185     usec | 50.9    usec  | 118     usec   |
| s3  | 4.17   usec | 348    usec | 120     usec | 264     usec  | 61.3    usec   |
|     |             |             |              |               |                |
| s4  | 1.73   msec |             | 182     usec | 50.5    usec  | 121     usec   |
| s5  | 1.71   msec |             | 181     usec | 50.6    usec  | 125     usec   |
| s6  | 4.29   usec |             | 122     usec | 423     usec  | 61.1    usec   |
|     |             |             |              |               |                |
| s7  | 3.1    usec | 1.4    usec | 1.24    usec | 0.932   usec  | 1.92    usec   |
| s8  | 4.07   usec | 1.54   usec | 1.28    usec | 0.997   usec  | 1.79    usec   |
| s9  | 5.91   usec | 1.25   usec | 0.749   usec | 0.407   usec  | 0.386   usec   |

注意:

# http://stackoverflow.com/q/3844948/
def checkEqualIvo(lst):
    return not lst or lst.count(lst[0]) == len(lst)

# http://stackoverflow.com/q/3844931/
def checkEqual6502(lst):
    return not lst or [lst[0]]*len(lst) == lst

 
 Code问答: codewenda.com
Stackoverflow:check if all elements in a list are identical

发表评论

电子邮件地址不会被公开。 必填项已用*标注

58 − 48 =