""" Some generic comparison utility functions. """ def generic_cmp(value1, value2): """ Generic comparator of values which uses the builtin '<' and '>' operators. Assumes the values can be compared that way. :param value1: The first value :param value2: The second value :return: -1, 0, or 1 depending on whether value1 is less, equal, or greater than value2 """ return -1 if value1 < value2 else 1 if value1 > value2 else 0 def iter_lex_cmp(seq1, seq2, cmp): """ Generic lexicographical compare function, which works on two iterables and a comparator function. :param seq1: The first iterable :param seq2: The second iterable :param cmp: a two-arg callable comparator for values iterated over. It must behave analogously to this function, returning <0, 0, or >0 to express the ordering of the two values. :return: <0 if seq1 < seq2; >0 if seq1 > seq2; 0 if they're equal """ it1 = iter(seq1) it2 = iter(seq2) it1_exhausted = it2_exhausted = False while True: try: val1 = next(it1) except StopIteration: it1_exhausted = True try: val2 = next(it2) except StopIteration: it2_exhausted = True # same length, all elements equal if it1_exhausted and it2_exhausted: result = 0 break # one is a prefix of the other; the shorter one is less elif it1_exhausted: result = -1 break elif it2_exhausted: result = 1 break # neither is exhausted; check values else: val_cmp = cmp(val1, val2) if val_cmp != 0: result = val_cmp break return result def iter_in(value, seq, cmp): """ A function behaving like the "in" Python operator, but which works with a a comparator function. This function checks whether the given value is contained in the given iterable. :param value: A value :param seq: An iterable :param cmp: A 2-arg comparator function which must return 0 if the args are equal :return: True if the value is found in the iterable, False if it is not """ result = False for seq_val in seq: if cmp(value, seq_val) == 0: result = True break return result