2012-07-30 15 views
9

Mi piacerebbe confrontare più oggetti e restituire True solo se tutti gli oggetti non sono uguali tra di loro. Ho provato ad usare il codice qui sotto, ma non funziona. Se obj1 e obj3 sono uguali e obj2 e obj3 non sono uguali, il risultato è True.Python: determinare se un elemento in sequenza è uguale a qualsiasi altro

obj1 != obj2 != obj3 

Ho più di 3 oggetti da confrontare. Usando il codice qui sotto è fuori discussione:

all([obj1 != obj2, obj1 != obj3, obj2 != obj3]) 
+0

è il numero di oggetti fissi, o variabile? Sono elementi di un array o di singole variabili? –

risposta

20

@Michael La risposta di Hoffman è buona se gli oggetti sono tutti lavabili. In caso contrario, è possibile utilizzare itertools.combinations:

>>> all(a != b for a, b in itertools.combinations(['a', 'b', 'c', 'd', 'a'], 2)) 
False 
>>> all(a != b for a, b in itertools.combinations(['a', 'b', 'c', 'd'], 2)) 
True 
18

Se gli oggetti sono tutti hashable, allora si può vedere se una frozenset della sequenza di oggetti ha la stessa lunghezza della sequenza stessa:

def all_different(objs): 
    return len(frozenset(objs)) == len(objs) 

Esempio:

>>> all_different([3, 4, 5]) 
True 
>>> all_different([3, 4, 5, 3]) 
False 
+0

Accidenti! battermi di 10 secondi. – inspectorG4dget

+1

Si noti che questo non funzionerà se gli oggetti sono inattivi. – BrenBarn

+0

Questo non funziona se uno (o tutti) degli oggetti è inattaccabile (ad esempio un elenco) – mgilson

3

è possibile verificare che tutti gli elementi di una lista sono unici convertendolo in un set.

my_obs = [obj1, obj2, obj3] 
all_not_equal = len(set(my_obs)) == len(my_obs) 
4
from itertools import combinations 
all(x != y for x, y in combinations(objs, 2)) 
+1

Questo è O (n^2) confronti - MOLTO per elenchi di grandi dimensioni. – inspectorG4dget

6

Se gli oggetti sono nel calcolo dell'hash, ma ordinabile (ad esempio, le liste), allora si può trasformare la soluzione itertools da O (n^2) a O (n log n) di classificare:

def all_different(*objs): 
    s = sorted(objs) 
    return all(x != y for x, y in zip(s[:-1], s[1:])) 

Ecco un'implementazione completa:

def all_different(*objs): 
    try: 
     return len(frozenset(objs)) == len(objs) 
    except TypeError: 
     try: 
      s = sorted(objs) 
      return all(x != y for x, y in zip(s[:-1], s[1:])) 
     except TypeError: 
      return all(x != y for x, y in itertools.combinations(objs, 2)) 
+0

Il controllo dell'habability è troppo complesso (e anche leggermente errato). Il modo idiomatico per farlo in Python è provare a costruire un 'frozenset()' e prendere 'TypeError' se questo non riesce. (Il test è leggermente errato perché 'isinstance (obj, collections.Hashable)' essendo 'True' non garantisce che l'oggetto sia effettivamente lavabile, controlla solo se l'oggetto ha un tipo che gli consente in linea di principio di essere sottoposto a hash. ([],) 'come esempio contatore.) –

+0

@SvenMarnach grazie, risolto. – ecatmur

Problemi correlati