6

I am doing this following:

if ycoords[0] > 0 and ycoords[1] > 0 and ycoords[2] > 0:
    # do stuff

Can you shorten this code by doing something like:

if (ycoords[0] and ycoords[1] and ycoords[2]) > 0:
    # do stuff
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
Edward Garemo
  • 434
  • 3
  • 13

3 Answers3

9

Yes, you could use all:

if all(x > 0 for x in ycoords):

or ycoords[:3] if ycoords has more than 3 elements.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
3

No, you can however simply use min to simplify the test syntactically:

if min(ycoords[0],ycoords[1],ycoords[2]) > 0:
    # do stuff

and given that ycoords exactly has three elements, even shorter:

if min(*ycoords) > 0:
    #do stuff

you can here, as @Tagc says, omit the asterisk (*):

if min(ycoords) > 0:
    #do stuff

but this will result in some overhead.

Another option is to use an all:

if all(x > 0 for x in [ycoords[0],ycoords[1],ycoords[2]]):
    # do stuff

or again, if ycoords contains only these three elements:

if all(x > 0 for x in ycoords):
    # do stuff
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • 3
    "even shorter: `if min(*ycoords) > 0`". And *even* shorter: `if min(ycoords) > 0`. – Tagc Jan 20 '17 at 10:31
1

Something that is not intuitive is that and:

"neither and nor or restrict the value and type they return to False and True, but rather return the last evaluated argument"

Just open a python terminal and do:

>> 4 and 3
3

Why is this important to take in account?

You might think that:

(ycoords[0] and ycoords[1] and ycoords[2]) > 0 

is equivalent to:

ycoords[0] > 0 and ycoords[1] > 0 and ycoords[2] > 0

or that is equivalent to:

(bool(ycoords[0]) and bool(ycoords[1]) and bool(ycoords[2])) > 0

but it's instead equivalent to:

ycoords[2] > 0

So, be careful because the interpreter is not doing what you think is doing.