Reputation: 1471
I have two lists
a = [1, 4, 12]
b = [2, 13]
I want to know if values in list b
are between two values in list a
So, in this case, 2 will fall between 1 and 4. 13 will not fall between any numbers.
I have tried bisect
function, but I couldn't get it work. I was able to use it with a single value and a list, but not two lists.
Upvotes: 0
Views: 2501
Reputation: 5615
If you don't care much about performance, here's a pythonic solution-
def betwn(rangelist, valuelist):
# Get list of all ranges between each consecutive number of rangelist
rgs = [range(rangelist[n], rangelist[n + 1]) for n in range(len(rangelist) - 1)]
# A function to check whether a given element exists between 2 consecutive numbers of rangelist
verifyfunc = lambda e: any(e in r for r in rgs)
# Return the qualifying elements from valuelist
return [e for e in valuelist if verifyfunc(e)]
>>> betwn([1, 4, 12], [2, 13])
[2]
Upvotes: 1
Reputation: 82899
Maybe there's some subtlety that I do not get, but unless I am mistaken, you only have to check whether the elements are between the min
and max
from a
. This is independent of whether the elements in a
are sorted, or whether the values from b
have to be between consecutive values from a
. As long as they are between the min
and max
, there has to be a "segment" in a
those values are in.
>>> a = [1, 4, 12]
>>> b = [2, 13]
>>> n, m = min(a), max(a)
>>> [n < x < m for x in b]
[True, False]
That is, of course, only if (a) you do not need which numbers they are in between, and (b) if not all values in b
have to be in the same interval.
If you think I missed something, please comment.
Upvotes: 4
Reputation: 266
It really depends on what you want it to return. I wrote a code that will return the first pattern that it finds, but with some changes I'm sure it would not be difficult to return all combinations.
def get_between(a, b):
a, b = sorted(a), sorted(b)
for b_value in b:
smaller = None
greater = None
for a_value in a:
if b_value > a_value:
smaller = a_value
elif b_value < a_value:
greater = a_value
if smaller and greater:
return f"{b_value} is between {smaller} and {greater}"
return "There is no such combination"
a = [1, 4, 12]
b = [2, 13]
print(get_between(a, b))
The output on that case will be 2 is between 1 and 4
, but you can adapt the return value to be whatever you want.
Upvotes: 2
Reputation: 35512
You can keep two running indices to get a list of all elements that fall between values:
def get_between(arr1, arr2):
# first sort the arrays
arr1 = sorted(arr1)
arr2 = sorted(arr2)
# keep two indices into them
i1 = 0
i2 = 0
# keep track of the values between two values
ret = []
while i1 < len(arr1) - 1 and i2 < len(arr2):
# we're too small to be between a value
# so we should increase the second index
if arr2[i2] < arr1[i1]:
i2 += 1
# we're too large to be between a value
# so we should increase the first index
elif arr2[i2] > arr1[i1 + 1]:
i1 += 1
# we are between a value
# so we should append to the return array
# and move on to the next element
else:
ret.append(arr2[i2])
i2 += 1
return ret
get_between([1, 4, 12], [2, 8, 13]) # [2, 8]
Upvotes: 1