测试所有 N 个变量是否不同

Test if all N variables are different

我想创建一个所有选定变量都不相等的条件。 到目前为止,我的解决方案是比较每对不能很好缩放的对:

if A!=B and A!=C and B!=C:

我想对多个变量进行相同的检查,比如说五个或更多,而且这么多变量会让人很困惑。我该怎么做才能让它更简单?

创建一个集合并检查集合中元素的数量是否与您传递给它的列表中的变量数量相同:

>>> variables = [a, b, c, d, e]
>>> if len(set(variables)) == len(variables):
...     print("All variables are different")

一个集合没有重复的元素,所以如果你创建一个集合并且它的元素数量与原始列表中的元素数量相同,那么你就会知道所有元素彼此不同。

如果你可以散列你的变量(而且,呃,你的变量有一个有意义的__hash__),使用一个集合。

def check_all_unique(li):
    unique = set()
    for i in li:
        if i in unique: return False #hey I've seen you before...
        unique.add(i)
    return True #nope, saw no one twice.

O(n) 最坏情况。 (是的,我知道您也可以 len(li) == len(set(li)),但如果找到匹配项,此变体 returns 会提前)

如果您无法散列您的值(无论出于何种原因)但可以对它们进行有意义的比较:

def check_all_unique(li):
    li.sort()
    for i in range(1,len(li)):
       if li[i-1] == li[i]: return False
    return True 

O(nlogn),因为排序。基本上,对所有内容进行排序,然后进行成对比较。如果两个东西相等,它们应该并排排列。 (如果由于某种原因,您的 __cmp__ 没有对彼此相邻的相同事物进行排序,1. wut 和 2. 请继续下一个方法。)

如果 ne 是您唯一的操作员....

import operator
import itertools
li = #a list containing all the variables I must check
if all(operator.ne(*i) for i in itertools.combinations(li,2)):
   #do something

我基本上是使用 itertools.combinations 来配对所有变量,然后使用 operator.ne 来检查不相等。这具有 O(n^2) 的最坏情况时间复杂度,尽管它仍然应该短路(因为生成器和 all 是惰性的)。如果你完全确定neeq是相反的,你可以用operator.eqany代替。

附录:Vincent 写了一个 更易读的 itertools 变体版本,看起来像

import itertools
lst = #a list containing all the variables I must check
if all(a!=b for a,b in itertools.combinations(lst,2)):
   #do something

附录2:呃,对于足够大的数据集,排序变体应该使用heapq。仍然是 O(nlogn) 最坏的情况,但 O(n) 最好的情况。就像

import heapq
def check_all_unique(li):
    heapq.heapify(li) #O(n), compared to sorting's O(nlogn)
    prev = heapq.heappop(li)
    for _ in range(len(li)): #O(n)
       current = heapq.heappop(li) #O(logn)
       if current == prev: return False
       prev = current
    return True 

将值放入容器类型中。然后循环遍历容器,比较每个值。大约需要 O(n^2).

伪代码:

a[0] = A; a[1] = B ... a[n];

for i = 0 to n do
  for j = i + 1 to n do
      if a[i] == a[j]
         condition failed

您可以枚举一个列表并检查所有值是否都是该值在列表中的第一次出现:

a = [5, 15, 20, 65, 48]
if all(a.index(v) == i for i, v in enumerate(a)):
    print "all elements are unique"

由于 Python 的 all() 函数的行为,这允许在检测到第一个重复项后进行短路。

或者等效地,枚举一个列表并检查是否有任何值不是该值在列表中第一次出现:

a = [5, 15, 20, 65, 48]
if not any(a.index(v) != i for i, v in enumerate(a)):
    print "all elements are unique"