The Other Guy
The Other Guy

Reputation: 576

Python series algorithm

I have a list of this sort :

numbers = [12, None, None, 17, 20, None, 28]

What's the best path to consider in order to fill in None values with appropriate numbers so that the None values get numbers in between the defined values.

Example :

numbers = [12, **14**, **16**, 17, 20, **24**, 28]

Upvotes: 0

Views: 107

Answers (2)

motoku
motoku

Reputation: 1581

I didn't at first see the requirement of the replaced index needing to be in between.

def interpolate(x):
    while None in x:
        indexa = x.index(None)
        indexb = indexa + 1
        while (x[indexb]) is None:
            indexb = indexb + 1
        indexb = indexb - 1
        index = int((indexa + indexb) / 2)
        x[index] = y(index, x)
    return x


def y(j, x):
    a, b, j2 = 0.0, 0.0, j
    while x[j2] is None and j2 > -1:
        j2 = j2 - 1
    a = x[j2]
    while x[j] is None:
        j = j + 1
    b = x[j]
    return int((a + b) / 2)

print(interpolate([12, None, None, 17, 20, None, 28]))
print(interpolate([12, None, None, None, 17, 20, None, 28]))
print(interpolate([12, None, None, None, None, 17]))
nones = lambda i: [None for nothing in range(i)]
for i in range(10):
    print(interpolate([0] + nones(i) + [10]))

Output:

[12, 14, 15, 17, 20, 24, 28]
[12, 13, 14, 15, 17, 20, 24, 28]
[12, 13, 14, 15, 16, 17]
[0, 10]
[0, 5, 10]
[0, 5, 7, 10]
[0, 2, 5, 7, 10]
[0, 2, 5, 7, 8, 10]
[0, 2, 3, 5, 7, 8, 10]
[0, 2, 3, 5, 6, 7, 8, 10]
[0, 1, 2, 3, 5, 6, 7, 8, 10]
[0, 1, 2, 3, 5, 6, 7, 8, 9, 10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1124100

Interpolating on the fly to create a linear interpolation:

def interpolate(l):
    last = None
    count = 0
    for num in l:
        if num is None:
            # count the number of gaps
            count += 1
            continue
        if count:
            # fill a gap based on the last seen value and the current
            step = (num - last) / float(count + 1)
            for i in xrange(count):
                yield last + int(round((1 + i) * step))
            count = 0
        last = num
        yield num

Demo:

>>> list(interpolate([12, None, None, 17, 20, None, 28]))
[12, 14, 15, 17, 20, 24, 28]

Upvotes: 1

Related Questions