'Python: Multiple "or" Statements [duplicate]

I'm working on building a snake clone using Turtle. Is there a cleaner/more pythonic way to write the conditional inside of this function?

    def out_of_bounds(self, lst):
        if lst.xcor() < -260 or lst.xcor() > 260 or lst.ycor() < -260 or lst.ycor() > 260:
        return True


Solution 1:[1]

You can remove two of the comparisons by taking their absolute value

def out_of_bounds(self, lst):
    return abs(lst.xcor()) > 260 or abs(lst.ycor()) > 260

Solution 2:[2]

Make the boolean expression return directly, also multiline using brackets:
(to remove the need of \ at the end of lines)

Your function returns True or None, which works since None is Falsy. Better to return False if the expression fails.

def out_of_bounds(self, lst):
    return (
        lst.xcor() < -260 
        or lst.xcor() > 260 
        or lst.ycor() < -260 
        or lst.ycor() > 260
    )

Solution 3:[3]

Mostly, I'd reverse those tests and negate the result, we stay in the same condition but more readable.

In the parenthesis we test with xcor and ycor are in the ±260 interval, then we negate.

def out_of_bounds(self, lst):
    return not (-260 <= lst.xcor() <= 260 and -260 <= lst.ycor() <= 260)

Solution 4:[4]

Instead of x < -a or x > a you can write not -a <= x <= a. Some may find it more readable.

Solution 5:[5]

you can use any, it will return true if at least one of the values is true, inside this list you can put all your conditions

def out_of_bounds(self, lst) -> bool:
    return any([
        lst.xcor() < -260, 
        lst.xcor() > 260,
        lst.ycor() < -260, 
        lst.ycor() > 260
    ])

Solution 6:[6]

You can use the fact that upper & lower bounds are in common for x & y:

def out_of_bounds(self, lst):
    x, y = lst.xcor(), lst.ycor()
    ub_checks = map(int(-260).__gt__, (x, y)) # check if less than upper bound
    lb_checks = map(int(260).__lt__, (x, y)) #  check if greater than lower bound
    return any(ub_checks) or any(lb_checks)

Solution 7:[7]

It looks like the builtin abs function, which returns the absolute value, could cut down the amount of ors you need.

return abs(lst.xcor()) > 260 or abs(lst.ycor() > 260:

In general, with long chains of or or and statements, though, I like to use any or all.

# Note that you wouldn't want to collect values into a list if these are
# demanding functions, because you lose the benefit of shortcircuiting
any([True, False]) # True
all([True, False]) # False

Solution 8:[8]

To answer your question, this is the only solution I know about.

However, even thought there is not much information about your work I would guess lst.xcor() and lst.ycor() get/calculate the coordinates of something (your mouse pointer?).

For speed purpose I would do :

    def out_of_bounds(self, lst):
        X = lst.xcor()
        Y = lst.ycor()
        if X < -260 or X > 260 or Y < -260 or Y > 260:
            return True

Since you have to call a function it takes time, and calling it one time instead of two is (a little) faster.

and it even look a bit cleaner

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Cory Kramer
Solution 2 ivvija
Solution 3 ljmc
Solution 4 TDG
Solution 5
Solution 6 cards
Solution 7
Solution 8 Ren