Test if all N variables are different

十年热恋 提交于 2021-02-04 15:41:50

问题


I want to make a condition where all selected variables are not equal. My solution so far is to compare every pair which doesn't scale well:

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

I want to do the same check for multiple variables, say five or more, and it gets quite confusing with that many. What can I do to make it simpler?


回答1:


Create a set and check whether the number of elements in the set is the same as the number of variables in the list that you passed into it:

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

A set doesn't have duplicate elements so if you create a set and it has the same number of elements as the number of elements in the original list then you know all elements are different from each other.




回答2:


If you can hash your variables (and, uh, your variables have a meaningful __hash__), use a set.

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) worst case. (And yes, I'm aware that you can also len(li) == len(set(li)), but this variant returns early if a match is found)

If you can't hash your values (for whatever reason) but can meaningfully compare them:

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), because sorting. Basically, sort everything, and compare pairwise. If two things are equal, they should have sorted next to each other. (If, for some reason, your __cmp__ doesn't sort things that are the same next to each other, 1. wut and 2. please continue to the next method.)

And if ne is the only operator you have....

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

I'm basically using itertools.combinations to pair off all the variables, and then using operator.ne to check for not-equalness. This has a worst-case time complexity of O(n^2), although it should still short-circuit (because generators, and all is lazy). If you are absolutely sure that ne and eq are opposites, you can use operator.eq and any instead.

Addendum: Vincent wrote a much more readable version of the itertools variant that looks like

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

Addendum 2: Uh, for sufficiently large datasets, the sorting variant should possibly use heapq. Still would be O(nlogn) worst case, but O(n) best case. It'd be something like

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 



回答3:


Put the values into a container type. Then just loop trough the container, comparing each value. It would take about O(n^2).

pseudo code:

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



回答4:


You can enumerate a list and check that all values are the first occurrence of that value in the list:

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

This allows for short-circuiting once the first duplicate is detected due to the behaviour of Python's all() function.

Or equivalently, enumerate a list and check if there are any values which are not the first occurrence of that value in the list:

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


来源:https://stackoverflow.com/questions/31505075/test-if-all-n-variables-are-different

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!