zingy
zingy

Reputation: 811

getting a boundary of an item from another list

I have a list which is like,

tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22] (which is sorted)

I have another list which is,

newlist = [0.0, 0.04, 0.08, 0.12, 0.16, 0.2] (numbers with a difference of 0.04)

I have to go through each item of the second list and check in which boundary (between which two numbers from the tlist) the number lies.

Like if I am checking for first item which is '0.0' from the second list then it falls between '0.0' and '0.07' in the first list.

Similarly, the next item in the second list which is '0.04' falls between '0.0' and '0.07' again in the first file.

So, for every item checked from the second list it should know its boundary. And it should set the boundaries. The result could be like, the range for '0.0' is x to y where x = 0.0 and y = 0.07.

If there is a number in tlist which is exactly the same as one of the numbers from the newlist then the program should neglect it or it can print a statement like "no boundary possible" and continue with the next number.

How do I put this into code. Thank you.

Upvotes: 4

Views: 279

Answers (8)

agf
agf

Reputation: 176760

Using the code you posted from your question Unexpected output from Newton's method, here a time function which correctly matches the boundary:

def time() :
    t_u = 0
    i = 0
    while i < len(tlist) - 1:
        # if the number is in the range
        # do the calculations and move to the next number
        if t_u > tlist[i] and t_u < tlist[i + 1] :
            print "\n The t_u value:", t_u, 'is between',
            print "start:", tlist[i], " and end: ", tlist[i+1]
            poly = poly_coeff(tlist[i], tlist[i + 1], t_u)
            Newton(poly)
            t_u = t_u + 0.04 # regular time interval
        # if the number is at the boundary of the range
        # go to the next number without doing the calculation
        elif t_u == tlist[i] or t_u == tlist[i + 1] :
            print "\n The t_u value:", t_u, 'is on the boundary of',
            print "start:", tlist[i], " and end: ", tlist[i+1]
            t_u = t_u + 0.04 # regular time interval
        # if the number isn't in the range, move to the next range
        else :
            i += 1

Upvotes: 2

jterrace
jterrace

Reputation: 67063

You can use the bisect module for this:

import bisect
def bisect_range(sortedlist, tofind):
    for t in tofind:
        loc = bisect.bisect_right(sortedlist, t)
        yield (sortedlist[loc-1], sortedlist[loc])

tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22]
newlist = [0.0, 0.04, 0.08, 0.12, 0.16, 0.2]
print list(bisect_range(sorted(tlist), newlist))

This is O(N * log(M)) where M is the length of the sorted list and N is the length of the items being searched, because the bisect_right function is O(log(M)) and we are calling it once for each item in the search list of length N. Sorting the initial list (if it's not already sorted) is O(M * log(M)).

Upvotes: 2

Evpok
Evpok

Reputation: 4485

Somewhat plain and assuming tlist is sorted

def find_interval(tlist, item):
    for lower, upper in zip(tlist[:-1], tlist[1:]):
        if lower <= item < upper:
            return (lower, upper)
    return None # Or raise some "IntervalNotFoudException"

print((find_interval(tlist, item) for item in newlist))

Edit : Made it shorter using zip

Upvotes: 2

Zach Kelling
Zach Kelling

Reputation: 53819

Simple approach using enumerate:

for n in newlist:
    for i, t in enumerate(tlist):
        if t > n:
            # found upper boundry, previous must be equal or lower
            upper, lower = t, tlist[i-1]
            break
    print lower, n, upper

Upvotes: 4

MattH
MattH

Reputation: 38247

Many solutions... here's one using iterators:

tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22]
newlist = [0.0, 0.04, 0.08, 0.12, 0.16, 0.2]

def range_finder(a,b):
  iter_a = iter(a)
  lower_a, upper_a = iter_a.next(), iter_a.next()
  for item in b:
    while True:
      if lower_a <= item < upper_a:
        print "%s is %s to %s" % (item,lower_a,upper_a)
        break
      else:
        lower_a = upper_a
        upper_a = iter_a.next()

range_finder(tlist,newlist)

Producing:

0.0 is 0.0 to 0.07
0.04 is 0.0 to 0.07
0.08 is 0.07 to 0.13
0.12 is 0.07 to 0.13
0.16 is 0.15 to 0.2
0.2 is 0.2 to 0.22

Upvotes: 0

Facundo Casco
Facundo Casco

Reputation: 10585

>>> tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22]
>>> newlist = [0.0, 0.04, 0.08, 0.12, 0.16, 0.2]
>>> def getrange(x):
...     for i in range(len(tlist)):
...         if tlist[i] > x:
...             return tlist[max(0, i-1)], tlist[i]
>>> [getrange(x) for x in newlist]
8: [(0.0, 0.07),
 (0.0, 0.07),
 (0.07, 0.13),
 (0.07, 0.13),
 (0.15, 0.2),
 (0.2, 0.22)]

Does this help?

Upvotes: 2

Brent Newey
Brent Newey

Reputation: 4509

tlist = [0.0, 0.07, 0.13, 0.15, 0.2, 0.22]
newlist = [0.0, 0.04, 0.08, 0.12, 0.16, 0.2]

for n in newlist:
    print n
    for i in xrange(len(tlist) - 1):
        if tlist[i] <= n < tlist[i + 1]:
            print tlist[i], tlist[i + 1]
            break
    else:
        print "Not found"
    print ""

This prints out the following:

0.0
0.0 0.07

0.04
0.0 0.07

0.08
0.07 0.13

0.12
0.07 0.13

0.16
0.15 0.2

0.2
0.2 0.22

Assumptions: I assume you want inclusive on the lower bound, and not on the upper bound, and I assume your tlist is sorted.

Upvotes: 1

Shaunak
Shaunak

Reputation: 18018

If your First Array is Sorted, this should be pretty simple. for every number in the array 2 (call it 'z'), iterate once through array one and find the value with highest index which is smaller than z. This is your x. then find the smallest index of the value in array 1 which is greater or equal to 'z'. This is your y.

Hope that helps.Let me know if you need more explanation. Coding this should not be a big deal. If you get stuck while coding post the code and I can help you with it.

Thanks Shaunak

Upvotes: 1

Related Questions