Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Element-wise comparison for lists #324

Open
parautenbach opened this issue Jan 2, 2024 · 5 comments
Open

Element-wise comparison for lists #324

parautenbach opened this issue Jan 2, 2024 · 5 comments

Comments

@parautenbach
Copy link

# let's validate some rgb values
In [1]: [0, 0, 0] <= [255, 123, 5] <= [255, 255, 255]
Out[1]: True

# 256 > 255, so we expect false
In [2]: [0, 0, 0] <= [256, 123, 5] <= [255, 255, 255]
Out[2]: False

# how about a negative value? wait, what!?
In [3]: [0, 0, 0] <= [255, 123, -5] <= [255, 255, 255]
Out[3]: True

# ok, so a single element list works
In [8]: [0] <= [-5] <= [255]
Out[8]: False

# let's avoid the chaining: still no
In [13]: ([0, 0, 0] <= [255, 123, -5]) and ([255, 123, -5] <= [255, 255, 255])
Out[13]: True

# put the negative element first: now it "works"
In [21]: [0, 0, 0] <= [-5, 123, 2555] <= [255, 255, 255]
Out[21]: False

It seems that Python will only compare the first elements of each list and continue.

@shiracamus
Copy link

The same result is obtained in JavaScript.

> [0, 0, 0] <= [255, 123, 5] && [255, 123, 5] <= [255, 255, 255]
true
> [0, 0, 0] <= [256, 123, 5] && [256, 123, 5] <= [255, 255, 255]
false
> [0, 0, 0] <= [255, 123, -5] && [255, 123, -5] <= [255, 255, 255]
true
> [0] <= [-5] && [-5] <= [255]
false
> ([0, 0, 0] <= [255, 123, -5]) && ([255, 123, -5] <= [255, 255, 255])
true
> [0, 0, 0] <= [-5, 123, 2555] && [-5, 123, 2555] <= [255, 255, 255]
false

@lezcano
Copy link

lezcano commented Jan 3, 2024

Python uses the lexicographic order, same as C++ and most languages really.

@pavanbadempet
Copy link

pavanbadempet commented Jan 30, 2024

As shiracamus and lezcano have already mentioned, pretty much every other language uses the same implementation as it is consistent with the general idea of lexicographical ordering. If you really want you could create a custom class and maybe override how the comparison operators work for specific use case.

class CustomList(list):
    def __le__(self, other):
        return all(x <= y for x, y in zip(self, other))

    def __ge__(self, other):
        return all(x >= y for x, y in zip(self, other))

    def __lt__(self, other):
        return all(x < y for x, y in zip(self, other))

    def __gt__(self, other):
        return all(x > y for x, y in zip(self, other))

def test_custom_list():
    assert CustomList([0, 0, 0]) <= CustomList([255, 123, 5]) <= CustomList([255, 255, 255])
    assert not CustomList([0, 0, 0]) <= CustomList([256, 123, 5]) <= CustomList([255, 255, 255])
    assert CustomList([0, 0, 0]) <= CustomList([255, 123, -5]) <= CustomList([255, 255, 255])
    assert not CustomList([0]) <= CustomList([-5]) <= CustomList([255])
    assert not CustomList([0, 0, 0]) <= CustomList([-5, 123, 2555]) <= CustomList([255, 255, 255])

# You can run these test cases
test_custom_list()

In this example, I created a Custom class that inherits from the built-in list class and overrides the less than or equal (le), greater than or equal (ge), less than (lt), and greater than (gt) comparison methods.

@nifadyev
Copy link
Contributor

Hey @satwikkansal , what are your thoughts about this snippet? Should it be included in wtfpython?

@satwikkansal
Copy link
Owner

I agree with others that the behavior is consistent across programming languages. It's not a surprising behaviour, although I think it's still a good piece to include with the following changes;

  • Instead of comparing a 3 element list, let's use a two-element one, as that's easier to follow through. Instead of having a reference to RGB we can have a reference to x-y coordinates on a plane.
  • It's more interesting when we also cover the case where the first element is the same. And instead of <= use <. A user would want to understand what happens when the first element is the same.
  • Citations to the documentation, and a note that this consistent behaviour across all the popular languages, not a Python specific thing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants