如果所有N个变量都不同,则测试Python

时间:2015-07-19 19:29:03

标签: python logical-operators boolean-logic idiomatic

我目前正在做一个程序而且我已经搜索过但我找不到解决方案; 我的问题是我想要制作一个条件,其中所有选择的变量都不相等,我可以这样做,但只有长行的文本,有更简单的方法吗? 到目前为止,我的解决方案是:

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

但我想为几组五个变量做这件事,而且很多人都很困惑。我该怎么做才能让它变得更简单?

4 个答案:

答案 0 :(得分:19)

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

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

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

答案 1 :(得分:5)

如果您可以散列变量(并且,呃,您的变量有一个有意义的__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)),但如果找到匹配项,此变体会提前返回)

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

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 

答案 2 :(得分:0)

将值放入容器类型中。然后只需循环容器,比较每个值。这需要大约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

答案 3 :(得分:0)

您可以枚举列表并检查所有值是列表中该值的第一个出现位置:

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"