9
votes

Python: déterminer si un élément de séquence est égal à tout autre

Je voudrais comparer plusieurs objets et retourner true code> uniquement si tous les objets ne sont pas égaux entre eux. J'ai essayé d'utiliser le code ci-dessous, mais cela ne fonctionne pas. Si obj1 et obj3 sont égaux et obj2 et obj3 ne sont pas égaux, le résultat est vrai code>. xxx pré>

J'ai plus de 3 objets à comparer. L'utilisation du code ci-dessous est hors de question: P>

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


1 commentaires

Le nombre d'objets fixes est-il fixé ou variable? Sont-ils des éléments d'un tableau ou de variables individuelles?


5 Réponses :


18
votes

Si les objets sont tous hachables, vous pouvez voir si un gelenset de la séquence d'objets a la même longueur que la séquence elle-même: xxx

: xxx


4 commentaires

Cela ne fonctionne pas si un (ou tout) des objets est un mal fabriqué (par exemple une liste)


Pourquoi grozenset au lieu de se mettre?


Je préfère gelenset lors de la création de jeux qui ne seront pas mutés.


Votre fonction ne serait-elle pas mieux nommée all_différent ?



3
votes

Vous pouvez vérifier que tous les éléments d'une liste sont uniques en la convertissant en un ensemble.

my_obs = [obj1, obj2, obj3]
all_not_equal = len(set(my_obs)) == len(my_obs)


0 commentaires

21
votes

La réponse de @Michael Hoffman est bonne si les objets sont tous hachables. Sinon, vous pouvez utiliser 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


0 commentaires

4
votes
from itertools import combinations
all(x != y for x, y in combinations(objs, 2))

1 commentaires

C'est des comparaisons O (N ^ 2) - beaucoup pour les grandes listes.



6
votes

Si les objets ne sont pas malsabinables mais commandables (par exemple, des listes), vous pouvez transformer la solution iTertools code> de O (n ^ 2) sur O (n log n) par tri:

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))


1 commentaires

Le chèque de hachabilité est beaucoup trop complexe (et aussi légèrement faux). La manière idiomatique de le faire dans Python est d'essayer de construire un gelenget () et attraper typeError si cela échoue. (Le test est légèrement faux parce que isinstance (obj, collections.hashable) étant true ne garantit pas que l'objet est réellement hashable. Il vérifie uniquement si l'objet a un type qui le permet en principe d'être haché. Essayez ([],) comme exemple d'exemple.)