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 · 3 comments
Open

Element-wise comparison for lists #324

parautenbach opened this issue Jan 2, 2024 · 3 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.

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

4 participants