Question: I want to sort a list of pairs primarily by a float, and secondarily by an integer. The problem is with comparing floats for equality--in many cases we get an arbitrary comparison instead of resorting to the secondary order. Example my_list = [ (0, 1.2), (2, 0.07076863960397783), (1, 0.07076863960397785), (4, 0.02) ]  I want to sort primarily by the float values, and secondarily by the integers. Running sorted(my_list, key=lambda x: (x[1], x[0])) returns this: [(4, 0.02), (2, 0.07076863960397783), (1, 0.07076863960397785), (0, 1.2)]  But since the two floats are so close that they should really be considered equal, the desired order is this: [(4, 0.02), (1, 0.07076863960397785), (2, 0.07076863960397783), (0, 1.2)]  How do I incorporate math.isclose or np.isclose into the sorting? My attempt My current approach is to wrap the floats into a class that performs the comparisons using the numpy's isclose. class FloatComparisonWrapper: def __init__(self, num): self.value = num def __lt__(self, other): return self.__ne__(other) and self.value < other.value def __gt__(self, other): return self.__ne__(other) and self.value > other.value def __eq__(self, other): return np.isclose(self.value, other.value) def __ne__(self, other): return not self.__eq__(other) def __le__(self, other): return self.__eq__(other) or self.value <= other.value def __ge__(self, other): return self.__eq__(other) or self.value >= other.value  And then sorted(my_list, key=lambda x: (FloatComparisonWrapper(x[1]), x[0])) gives the correct ordering. Is this a good solution? Is it pythonic? Is it the best solution? Is there a quicker way to do it?

Answer:  Is this a good solution?  No. OP's approach is flawed for sorting purposes.  since the two floats are so close that they should really be considered equal  Consider if all values are nearly in the vicinity of of the same floating point value. Some pairs are "equal", other not. OP's goal fails as the compare does not form a Total order.  From a C point-of-view that may apply to Python as I see the issue is language agnostic. This will not work as compare(a, b), compare(b,c), compare(a,c) must form a consistent order.  When the same objects (consisting of size bytes, irrespective of their current positions in the array) are passed more than once to the comparison function, the results shall be consistent with one another. That is, for qsort they shall define a total ordering on the array, ... C1723 § 7.24.5 4.  Consider (2, float_before(x)), // Lowest value that "is close" to x. (1, x), (0, float_after(x)), // Greatest value that "is close" to x.  Even though float_before(x) and x are consecutive "equal" values, as proposed by OP, (as well as x, float_after(x)), the sorting will arrive at different (and possible inconclusive: e.g. infinite loop) results, depending on the order the compares are applied since compare(float_before(x), float_after(x)) are not equal.  A secondary compare should not be applied unless the first order values are equal. Nearly equal is insufficient as a ≈ b and b ≈ c may be true, but a ≈ cis not. With OP's nearly equal, a > b and b > c due their primary compares are equal, but the secondary makes them greater than ordered, and implies a > c. Yet since a is not close to c and the primary ordering is a < c. This contradicts a > c.   Is there a quicker way to do it?  I recommend to drop the isclose() "two floats are so close that they should really be considered equal" approach for the primary compare. Simply do a value compare. Get the functionality correct before attempting to make it faster. // Pseudo code if (primary_compare_as_equal(a,b)) return secondary compare(a,b) return primary_compare(a,b)