2017-08-30 1 views
2

J'ai une classe simple :Test si tous les objets ont la même valeur membre

class simple(object): 
    def __init__(self, theType, someNum): 
     self.theType = theType 
     self.someNum = someNum 

Plus tard dans mon programme, je crée plusieurs instanciations de cette classe, à savoir:

a = simple('A', 1) 
b = simple('A', 2) 
c = simple('B', 3) 
d = simple('B', 4) 
e = simple('C', 5) 

allThings = [a, b, c, d, e] # Fails "areAllOfSameType(allThings)" check 

a = simple('B', 1) 
b = simple('B', 2) 
c = simple('B', 3) 
d = simple('B', 4) 
e = simple('B', 5) 

allThings = [a, b, c, d, e] # Passes "areAllOfSameType(allThings)" check 

I besoin de tester si tous les éléments dans allThings ont la même valeur pour simple.theType. Comment écrirais-je un test générique pour cela, afin que je puisse inclure de nouveaux «types» dans le futur (par exemple D, E, F, etc.) et ne pas avoir à réécrire ma logique de test? Je peux penser à un moyen de le faire via un histogramme, mais je me suis dit qu'il y avait une façon «pythonique» de le faire.

Répondre

3

Il suffit de comparer chaque objet avec le type du premier élément, en utilisant la fonction all():

all(obj.theType == allThings[0].theType for obj in allThings) 

Il n'y aura pas IndexError si la liste est vide, aussi.

all() courts-circuits, donc si un objet n'est pas du même type que l'autre, la boucle se brise immédiatement et renvoie False.

2

Vous pouvez utiliser un itertools recipe for this: all_equal (copié verbatim):

from itertools import groupby 

def all_equal(iterable): 
    "Returns True if all the elements are equal to each other" 
    g = groupby(iterable) 
    return next(g, True) and not next(g, False) 

Ensuite, vous pouvez l'appeler avec une expression de générateur qui accède à l'attribut theType:

>>> allThings = [simple('B', 1), simple('B', 2), simple('B', 3), simple('B', 4), simple('B', 5)] 
>>> all_equal(inst.theType for inst in allThings) 
True 

>>> allThings = [simple('A', 1), simple('B', 2), simple('B', 3), simple('B', 4), simple('B', 5)] 
>>> all_equal(inst.theType for inst in allThings) 
False 

Étant donné qu'il est effectivement mis en recette dans la documentation Python semble être l'un des meilleurs moyens (ou au moins recommandés) pour résoudre ce genre de problème.