0

I have a 3D coordinate tuple (x, y, z). I want to test that none of the 3 co-ords of a given tuple are below (a, b, c) and none are higher than (d, e, f). Through trial, error, and reading these forums I've learned that:

(a, b, c) <= (x, y, z) <= (d, e, f)

doesn't work as the first expression evaluates, then gets that outcome (0 or 1) and uses it in the next evaluation, and so on. So now I tried:

((a, b, c) <= (x, y, z)) and ((x, y, z) <= (d, e, f))

This doesn't work either because when it hits a True in any of the three paired comparisons (a, x; b, y; c, z; etc), it results in True. As such, tuple comparisons work more like decimal values rather than three separate scalar variables. I need any failure of all three pair-comparisons (six in total) to produce a False result rather than any success to produce a True.

I hoped for a method as sweetly simple as a <= b <= c. What is a simple method of doing this with tuples that only produces True when all pair-wise comparisons pass?

3 Answers 3

4

Assuming your lower and upper bound as well as your point are three-tuples, try this:

lower = 1,2,3
upper = 5,2,7
xyz = 2,3,4

all(u <= j <= v for u, j, v in zip(lower, xyz, upper))

Or just compare them individually:

(a <= x <= d) and (b <= y <= e) and (c <= z <= f)
Sign up to request clarification or add additional context in comments.

1 Comment

I want to say both you and falsetru gave the best answers. After mulling over falsetru's response, I was coming to the pythonic method that you came up with, Tobias. Thanks to you both!
3

According to Expression - Comparison:

Tuples and lists are compared lexicographically using comparison of corresponding elements. ...

Define your own comparison function.

>>> def lte(x, y):
...     return all(a <= b for a, b in zip(x, y))
... 
>>> lte((1,2,3), (2,3,4))
True
>>> lte((1,2,3), (0,3,4))
False
>>> lte((1,2,3), (2,3,4)) and lte((2,3,4), (3,4,5))
True
>>> lte((1,2,3), (2,3,4)) and lte((2,3,4), (3,2,5))
False

Comments

1

Through trial, error, and reading these forums I've learned that [...] doesn't work...

Except that it does, since Python chains relational operators.

>>> 3 < 4 < 5
True
>>> 5 > 4 > 3
True

This doesn't work either because when it hits a True in any of the three paired comparisons [...], it results in True.

Except that Python compares all elements in both sequence operands (of the same type).

>>> (1, 2, 3) >= (1, 2, 4)
False

Please verify that you are in fact using Python, since both of your observations are false in it.

3 Comments

When I do print (35, 43, 29) <= (40 , 40, 40), I get True. The answer I want my testing to give me is False, as the 43 is not less than or equal to 40. Do you get something different, or do I have my less thans and greater thans mixed up again? :)
Then you need to specify that in the question.
If a<x, (a,b,c)<=(x,y,z) never checks the remaining values, as falsetru noted. OP did specify: when all pair-wise comparisons pass.

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.