damien
damien

Reputation: 51

Testing if a certain number is within a list of ranges

How do I test how many times a certain number is outside my list of ranges?

Example:

value = 1
Ranges_array = [[0, 2], [2, 4], [0, 3]]
output = 1

So, the output generated will be 1 because there is only one range where the value of 1 does not lie within.

Upvotes: 5

Views: 98

Answers (6)

Mark Reed
Mark Reed

Reputation: 95242

Well, those aren't actually Ranges, but two-element lists. You could use manual comparison, as in the other answers, but in my answer I turn them into actual Range objects.

Since Python's range(a,b) constructor is inclusive at a (that is, a is inside the range) and exclusive at b (b is outside the range), you have to add 1 to one of the endpoints if you want them both to be inclusive or exclusive. I assumed you wanted inclusive, so added 1 to the high end point:

sum(1 for a,b in Ranges_array if value not in range(a,b+1))

Upvotes: 4

vaultah
vaultah

Reputation: 46523

You could use sum and a generator expression:

>>> sum(not a <= value <= b for a, b in ranges_array)
1

a and b are lower and upper range bounds, respectively. a <= value <= b is a chained comparison, equivalent to a <= value and value <= b. The final return value is the number of times the not a <= value <= b expression evaluated to True.

We can get a slightly longer but more readable solution if we apply De Morgan's laws:

>>> sum(value < a or value > b for a, b in ranges_array)
1

Technically, you can use range as shown in other answers, but they will be slower in Python 3 (due to the creation of the range object) and much slower in Python 2 (because Python 2's range creates an actual list, and containment checks on lists are O(n)):

$ python3.6 -m timeit -s "a, b, value = 0, 1000, 500" "a <= value <= b"
10000000 loops, best of 3: 0.0343 usec per loop
$ python3.6 -m timeit -s "a, b, value = 0, 1000, 500" "value in range(a, b + 1)"
1000000 loops, best of 3: 0.28 usec per loop
$ python2.7 -m timeit -s "a, b, value = 0, 1000, 500" "value in range(a, b + 1)"
100000 loops, best of 3: 7.97 usec per loop

Upvotes: 2

nomoreabond2017
nomoreabond2017

Reputation: 150

Just a parellel solution:

my_value = 1
Ranges_array = [[0,2],[2,4],[0,3]]
output = 1

count = 0
for listt in Ranges_array:
    if not my_value in range(listt[0],listt[-1]):
        count+= 1

print count

Upvotes: 0

Kaushik NP
Kaushik NP

Reputation: 6781

Using list comprehension :

>>> sum([1 for x,y in ranges if not x<=value<=y])
=> 1

#OR

>>> len([1 for x,y in ranges if not x<=value<=y])
=> 1

Using generators (recommended as it will be faster) :

>>> sum(1 for x,y in ranges if not x<=value<=y)
=> 1

#driver value :

IN : ranges = [[0,2], [2,4], [0,3]]

Upvotes: 0

S.Doe
S.Doe

Reputation: 47

You could try:

value = 1
Ranges_array= [[0,2],
          [2,4],
          [0,3]]
output = 0
for r in Ranges_array:
    if value not in range(r[0], r[1]):
        output +=1

Upvotes: 0

WNG
WNG

Reputation: 3805

list comprehension should be enough.

output=len([k for k in Ranges_array if k[0]>value or k[1]<value])

Upvotes: 0

Related Questions