0

With Crystal, I can compare two numbers using the <==> operator. Example:

p! 1 <=> 1

Running this prints:

1 <=> 1 # => 0

The zero signifies that both numbers are equal. If the value is higher, it would return a positive number. If the value is lower, it returns a negative number. I'd like to know if such an operator exists with Python. Trying to use the <==> operator gives a syntax error:

>>> 1 <==> 1
File "<stdin>", line 1
1 <==> 1
    ^
SyntaxError: invalid syntax

I can obviously use something like this:

if 1 == 1:
   #equal
elif 1 < 1:
   #less than
else:
    #greater than

But I think it would be simpler to use a universal operator for comparing.

10
  • 1
    No such operator exists, but you can trivially define a function for this use-case Commented Jul 26, 2021 at 18:50
  • Related: Three-way comparing strings in Python 3 Commented Jul 26, 2021 at 18:51
  • 2
    The pythonic equivalent would be the cmp function, however this only exists in python 2 and not python 3. See stackoverflow.com/questions/22490366/how-to-use-cmp-in-python-3 for python 3 alternatives. Commented Jul 26, 2021 at 18:52
  • 3
    Languages that have this operator usually have a built-in sorting function that needs a 3-way result. Python doesn't have this type of sorting function, so it doesn't need the operator. Commented Jul 26, 2021 at 18:53
  • you could just subtract the values! Commented Jul 26, 2021 at 18:53

2 Answers 2

2

Even if you had such an operator, you still end up with the 3-way if:

if a <=> b == 0:
    # equal
elif a <=> b < 0:
    # less than
else:
    # greater than

so it doesn't really buy you much. It does mean you can avoid writing the comparison expression if it's complex:

compare = a <=> b
if compare == 0:
    ...

But that was apparently not useful enough for the Python designers to keep the built-in cmp() function that was in Python 2.x.

If you really want it, there are a number of implementations in How to use cmp() in Python 3?

Sign up to request clarification or add additional context in comments.

1 Comment

"you still end up with the 3-way if" - not if i'm storing the value in a database
0

To compare numbers and find out if they're greater or smaller in one go, you may be able to just use subtraction!

>>> 1-1
0
>>> 1-5
-4

However, if you wanted rich comparison, define __lt__ on a custom object

class Foo():
    def __init__(self, name, primary, secondary):
        self.name      = name
        self.primary   = primary
        self.secondary = secondary
    def __str__(self):
        return self.name
    def __repr__(self):
        return f"Foo({self})"
    def __lt__(self, other):
        base       = self.primary * 100 + self.secondary
        comparison = other.primary * 100 + other.secondary
        return base < comparison
>>> a = Foo("some A", 3,4)
>>> b = Foo("some other B", 2, 99)
>>> test = (a,b)
>>> test
(Foo(some A), Foo(some other B))
>>> sorted(test)
[Foo(some other B), Foo(some A)]

3 Comments

This would be good, but only for integers. I cannot compare strings like this. I guess my question didn't reflect that well.
I was just chewing on the language spec, so it certainly wasn't obvious! .. still, you can use the rich comparison to compare anything (including comparing many different properties of your custom class individually with their own rich comparisons!)
presumably there are many incomparable cases within crystal, even if it produces a result, for example sorting some non-homogenous collection, where you would need to define some custom comparator for each plausible case or let it fall back to identifier where the comparison isn't meaningful (like the memory address)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.