How to do this Ruby if-with-and in Python and not get list index out of range

Viewed 105

In Ruby I can do something like:

irb(main):001:0> x = []
=> []
irb(main):003:0> puts "hi ho" if x.count > 0 and x[0]
=> nil

Ruby first evaluates x.count >0 as false and does not bother to evaluate x[0].

In Python I can have for example a file with:

x = []
if x.count > 0 and x[0]:
  print "hi ho" 

When I run:

[onknows:/tmp] $ python test-if.py 
Traceback (most recent call last):
  File "test-if.py", line 2, in <module>
    if x.count > 0 and x[0]:
IndexError: list index out of range
[onknows:/tmp] 1

So Python evaluates x[0] as well although there is no reason to evaluate it. Is there a way to use only one if and not resort to nested if in Python? I don't want to do something like:

if x.count > 0:
  if x[0]:
     print "hi ho" 
4 Answers

Looks like you need len.

x = []
if len(x) > 0 and x[0]:
    print("hi ho")

So Python evaluates x[0] as well although there is no reason to evaluate it.

I'm assuming this would work for you, in its most basic form:

if len(x) > 0: 
    print("Hi Ho!")

This evaluates the length of X, and (if greater than 0) responds True.

However, if the variable "x" does not exist, it will error. Evaluating if "x" exists at all, and contains at least one item, is (I assume) what you're trying to accomplish with ...

if x[0]:
    print("Hi Ho!")

Python will evaluate to True if the variable exists and contains any value. It will evaluate to False if the variable exists, but does not contain a value. Python will error if the variable does not exist.

So, this may be what you're looking for...

try:
    if len(x) > 0:
        print("Hi Ho!")
    else:
        print("Variable does not seem to contain a value!")
except (NameError, AttributeError, ValueError): 
    print("Variable does not exist!")

EDIT:

Note,that if x exists as a list, but contains no values, len(x) will evaluate to 0. However, if you try to evaluate x[0] you will still get an error, but it is a IndexError rather than the "Variable doesn't exist" error.

Python supports short-circuiting on and so if the first argument is False the second one is not evaluated.

x.count > 0 is always true:

In [12]: [].count > 0
Out[12]: True

You should replace it with len(x) and it works correctly:

if len(x) > 0 and x[0]:
  # ...

Python does lazy evaluation on boolean expression when using and or or.

From the docs:

The expression x and y first evaluates x; if x is false, its value is returned; otherwise, y is evaluated and the resulting value is returned.

The expression x or y first evaluates x; if x is true, its value is returned; otherwise, y is evaluated and the resulting value is returned.

Python list method count() returns count of how many times obj occurs in list.

You should use len(x) to get the length of a list.

x = []
if len(x) > 0 and x[0]:
  print "hi ho" 
Related