Tzomas
Tzomas

Reputation: 704

How to compare two objects, but just not none attributes

i have this object.

class Token(object):
    def __init__(self, word = None, lemma = None, pos = None, head = None, synt = None):
        self.word = word.lower()
        self.lemma = lemma
        self.pos = pos
        self.head = head
        self.synt =synt

and in some point i fill some attributes. Now i need to compare 2 objects but just the attributes that they aren't None. Is there some simple way to make it?

I tried with nested if statements but it is confuse and doesn't work fine.

Something like this:

def compareTokens(t1,t2):
    if t1.word is not None and t1.word == t2.word:
        if t1.lemma is not None and t1.lemma == t2.lemma:
            if t1.pos is not None and t1.pos == t2.pos:
                return True
    else:
        return False

Ty

Upvotes: 0

Views: 187

Answers (2)

Lucas Godoy
Lucas Godoy

Reputation: 812

class Token(object):
    def __init__(self, word=None, lemma=None, pos=None, head=None, synt=None):
        self.head = head
        self.lemma = lemma
        self.pos = pos
        self.synt = synt
        # Whatch out with this. Before if word=None then word.lower() == Boom!
        self.word = word.lower() if word is not None else None

    def _cmp(self):
        """Attributes that your class use for comparison."""
        return ['word', 'lemma', 'pos']

def compare_tokens(t1, t2):
    assert(hasattr(t1, '_cmp'))
    assert(hasattr(t2, '_cmp'))
    unique = list(set(t1._cmp()) | set(t2._cmp()))
    for attr in unique:
        if (not hasattr(t1, attr) or not hasattr(t2, attr)):
            return False
        if (getattr(t1, attr) is None or
                getattr(t1, attr) != getattr(t2, attr)):
            return False
    return True

t1 = Token('word', 'lemma', 1, 'head1', 'synt1')
t2 = Token('word', 'lemma', 1, 'head2', 'synt2')
print compare_tokens(t1, t2)

Upvotes: 0

chepner
chepner

Reputation: 531125

If you invert the test, you can iterate over the desired attributes, returning False as soon as possible. Only if you reach the end of the for loop do you return True.

import operator

def compare_tokens(t1, t2):
    if any(x is None for x in operator.attrgetter('word', 'lemma', 'pos')(t1)
    for getter in [operator.attrgetter(x) for x in 'word', 'lemma', 'pos']:
        if getter(t1) is None or getter(t1) != getattr(t2):
            return False
    return True

Another option is to test all values in t1 before looking at t2:

def compare_tokens(t1, t2):
    getter = operator.attrgetter('word', 'lemma', 'pos')
    t1_values = getter(t1)
    if any(x is None for x in t1_values):
        return False
    return t1_values == getter(t2)

Upvotes: 3

Related Questions