Python 测试所有N个变量是否不同
我想做一个条件,所有选择的变量都不相等。 到目前为止,我的解决方案是比较每一对伸缩性不好的:Python 测试所有N个变量是否不同,python,logical-operators,boolean-logic,idioms,Python,Logical Operators,Boolean Logic,Idioms,我想做一个条件,所有选择的变量都不相等。 到目前为止,我的解决方案是比较每一对伸缩性不好的: if A!=B and A!=C and B!=C: 我想对多个变量做同样的检查,比如说五个或更多的变量,这会让很多人感到困惑。我可以做些什么使它更简单?创建一个集合,并检查集合中的元素数量是否与传递到其中的列表中的变量数量相同: >>> variables = [a, b, c, d, e] >>> if len(set(variables)) == len(va
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")
一个集合没有重复的元素,因此如果您创建一个集合,并且它的元素数量与原始列表中的元素数量相同,那么您就知道所有元素都是不同的。如果您可以散列变量(并且,呃,您的变量有一个有意义的
\uuuuuuuuuuuuuuuuuuu散列
),请使用集合
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),因为排序。基本上,对所有内容进行排序,并进行两两比较。如果两件事是相等的,它们应该排在一起。(如果由于某种原因,您的\uuuu cmp\uuuu
没有对相邻的相同内容进行排序,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.combines
来配对所有变量,然后使用operator.ne
来检查不相等性。这在最坏情况下的时间复杂度为O(n^2),尽管它仍然应该短路(因为生成器和all
是惰性的)。如果您完全确定ne
和eq
是相反的,则可以使用操作符.eq
和任意
附录:编写了一个更具可读性的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"
a = [5, 15, 20, 65, 48]
if not any(a.index(v) != i for i, v in enumerate(a)):
print "all elements are unique"
由于Python的all()函数的行为,一旦检测到第一个重复,就允许短路
或等效地,枚举一个列表并检查是否有任何值不是该值在列表中第一次出现:
a = [5, 15, 20, 65, 48]
if all(a.index(v) == i for i, v in enumerate(a)):
print "all elements are unique"
a = [5, 15, 20, 65, 48]
if not any(a.index(v) != i for i, v in enumerate(a)):
print "all elements are unique"
你到底在做什么,需要你检查那么多的条件?这有点代码味道。我同意@Makoto。什么要求你这么做?这听起来像是xy问题。这是一个检查5名候选人的选票的程序。基本上,它统计的是一个有1到5张优先票的名单,“1”票数最多的人被选为获胜者,但如果一个或多个“1”票数相同,则根据“2”优先票选择获胜者,如果票数相同,则进行“3”投票,依此类推。这有点冗长,但这就是任务集,我将其与代码的这一部分分开进行了分类。您能否添加一个示例,因为可能有一种更简单的方法来完成您想要的任务。此候选信息存储在哪里?它是一个显式类;也就是说,计票是一个明确表示的类吗?您最好发布该代码,因为您所要求的和您实际得到的有点不同……假定对象是可散列的,这也会首先创建整个集合,因此不能过早失败。当前两项不同时,for循环可能已经中止。因此,平均运行时间取决于数据中预期差异的频率。虽然这可能是一个很好的答案,但我觉得这并没有真正解决实际问题。询问者应该回来(希望)澄清,但这种回答只会进一步混淆一个人,而不是帮助任何事情。我不认为这有那么难看,特别是如果你去掉
operator.ne
。类似于all(a!=b表示a,b的组合(lst,2))
。更好的是,为什么不首先从数组开始呢。这非常适用于密切相关的变量,例如需要相互比较变量列表的情况。但是创建set(variables)
只需要O(n),而且非常快。是的,我没有考虑到这一点。是的,一个可能会优化。嵌套for循环(特别是在相同范围内)是一种代码味道,表明您正在做一些效率低下的事情……好吧,将来肯定会这样做。谢谢