-3

Let's say I have a list of numbers and that I want to "extend" that list to beyond a certain number of elements. How should I extend the list by adding elements that are respectively the mean of the preceding and following element?

numbers = [1, 2, 3, 4, 5]
minimumNumberOfElementsRequired = 15

# do magic here
# first iteration: [1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5]
# second iteration: [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]
# have sufficient number of elements => return list

print(numbers_extended)
# output: [1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]

The beginning of my attempt is as follows:

list1 = [1, 2, 3, 4, 5]
list2 = [1, 2, 3, 4, 5]
index = -1
iterator = iter(list1)
for x, y in zip(iterator, iterator):
    index += 1
    list2.insert(index, (x + y) / float(2))
d3pd
  • 7,935
  • 24
  • 76
  • 127

5 Answers5

1

I guess you could do something like:

while len(numbers) < minimumNumberOfElementsRequired:
    index = 1
    while index < len(numbers):
        numbers.insert(index, (numbers[index-1] + numbers[index]) / 2.0)
        index += 2

It seems a bit awkward, but it's the easiest way around the shifting indices caused by insertion.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
1

It's not the most elegant solution, but it works.

numbers = [1,2,3,4,5]
while len(numbers) < 15:
    new_numbers = []
    for i, value in enumerate(numbers[:-1]):
        mean = (value + numbers[i+1])/2.0
        new_numbers.extend([value, mean])
    numbers = new_numbers + numbers[-1:]
chepner
  • 497,756
  • 71
  • 530
  • 681
0

You can iterate through the numbers using index, compute mean of following elements, and insert it to the list at the right position. At the same time, you need to notice than index is actually i*2 because element are added to the list while ierating.

while len(numbers) < minimum_length:
    for i in range(len(numbers) - 1):
        j = i*2
        a, b = numbers[j], numbers[j + 1]
        mean = (a + b)/2
        numbers.insert(j + 1, mean)
Delgan
  • 18,571
  • 11
  • 90
  • 141
0

With reduce (as suggested by Yaroslav Admin).

addnew function accepts a list and an new item to append.

from functools import reduce    # if python3

numbers = [1, 2, 3, 4, 5]
minlen = 15

def addnew(lst, x):
    if lst:
        lst.append((lst[-1] + x)/2)
    lst.append(x)

    return lst

while len(numbers) <= minlen:
    numbers = reduce(addnew, numbers, [])

print(list(numbers))
pacholik
  • 8,607
  • 9
  • 43
  • 55
0

Here's an iterative way to do it:

try:
    from itertools import izip
except ImportError:  # Python 3
    izip = zip

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = iter(iterable), iter(iterable)
    next(b, None)
    return izip(a, b)

def add_means(num_list):
    r = [num_list[0]]
    for pair in pairwise(num_list):
        r.extend([sum(pair)/2.0, pair[1]])
    return r

def extend_list(numbers, min_elements):
    while len(numbers) < min_elements:
        numbers = add_means(numbers)

    return numbers

numbers = [1, 2, 3, 4, 5]
minimumNumberOfElementsRequired = 15

print(extend_list(numbers, minimumNumberOfElementsRequired))

Output:

[1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3, 3.25, 3.5, 3.75, 4, 4.25, 4.5, 4.75, 5]
martineau
  • 119,623
  • 25
  • 170
  • 301