0

Suppose I have n values in a list x = [1.2, -0.4, 3.5, ....] I need to check if at least one of them is below zero.

So basically, if I had only two values, I'd have written if x[0]< 0 or x[1] < 0

But now, I need to use the same or operator within a loop so as to check each one of the values in the list.

The command any(x) < 0 seems to return False every single time.

How would I have to go about it?

Acad
  • 161
  • 5

4 Answers4

6

any is not vectorized. You'd have to apply it on each object in x:

any(n < 0 for n in x)

n < 0 for n in x creates a generator that yields one value at a time from x, and is quite efficient since it is short-circuited, meaning it will break (and return True) as soon as it finds the first n that is < 0.

DeepSpace
  • 78,697
  • 11
  • 109
  • 154
1

You can also use numpy for vectorized operations

import numpy as np
x = np.array([1.2, -0.4, 3.5,0])
x<=0 # will return the array of boolean values

If you just need to check if the condition met or not then

any(x<=0) # will return true if array contains atleast one True
mad_
  • 8,121
  • 2
  • 25
  • 40
0

When using any() or all() the pc will check if the elements in the iterableare True or False. Thus, you need to add a list comprehension to create the iterable:

any([elt < 0 for elt in x])
Mathieu
  • 5,410
  • 6
  • 28
  • 55
  • The brackets are redundant. – xrisk Oct 18 '18 at 12:32
  • @Rishav Just to show the creation of the list. Might be a bit more clear for the OP. – Mathieu Oct 18 '18 at 12:33
  • @Rishav They are worse than redundant. `any` is lazy, meaning that it stops checking when the first `True` is met. With the brackets, you are forcing it to go through the entire list. The same holds for `all()`. – Ma0 Oct 18 '18 at 12:33
  • @Ev.Kounis True. and you could change them to `()` to create a generator. – Mathieu Oct 18 '18 at 12:34
  • @Ev.Kounis Not entirely correct. By using `[ ]` the entire list indeed has to be created in memory, but `any` will still be short-circuited so it will stop as soon as it finds the first trueish value.Consider: `class Foo(int): def __bool__(self): print('checked') ; return True ;; any([Foo(), Foo(), Foo()])` The output is a single `checked` – DeepSpace Oct 18 '18 at 12:39
  • @DeepSpace How can it be that the entire list is created in memory **and** `any` is short-circuited? Do you mean that it short-circuits while parsing the already created list? – Ma0 Oct 18 '18 at 12:47
  • @Ev.Kounis Yes. See https://docs.python.org/3.7/library/functions.html#any – DeepSpace Oct 18 '18 at 12:52
  • @Ev.Kounis Yes, it will have to create the full list in memory (more consuming than a generator) but it will still stop as soon as one of the element does not match the condition. i.e. it creates the list beforehand. – Mathieu Oct 18 '18 at 13:20
0

Basically you need to do the following:

any(value < 0 for value in X)

You can find a detailed explanation here

Oscar Bonilla
  • 339
  • 1
  • 16