sashosm353
sashosm353

Reputation: 21

add neigbouring elements in a list

How can I write a function which takes a list of integers and creates a new list with the same number of elements as the original list such that each integer in the new list is the sum of its neighbours and itself in the original list. For example, if a_list = [10, 20, 30, 40, 50], the new_list = [30, 60, 90, 120, 90].

I tried a list comprehension;

def sum_neighbours(a_list):
    b_list = a_list
    li = [x+y for x in a_list for y in b_list]
    return li

print(sum_neighbours([10, 20, 30, 40, 50]))

Which gave me;

[20, 30, 40, 50, 60, 30, 40, 50, 60, 70, 40, 50, 
 60, 70, 80, 50, 60, 70, 80, 90, 60, 70, 80, 90, 100]

I then tried a for loop;

def sum_neighbours(a_list):
    element1 = a_list[0]
    new_list = []
    for element in a_list:
        element1 += element
        new_list += element1
    return new_list

print(sum_neighbours([10,20,30,40,50]))

Which threw a TypeError: 'int' object is not iterable

But in both cases I don't think my ideas/attempts are on the right track... I would really appreciate any help, hints, tips that more experienced people may have.

Upvotes: 2

Views: 1183

Answers (3)

Anthony Sigogne
Anthony Sigogne

Reputation: 71

Here is my one line solution with zip :

def sum_neighbours(a) :
    return [sum(x) for x in [(a[0],a[1])]+zip(a,a[1:],a[2:])+[(a[-2],a[-1])]]

print sum_neighbours([10, 20, 30, 40, 50]) # display [30, 60, 90, 120, 90]

with :

  • a, the original list
  • zip(a,a[1:],a[2:]), 3-tuples generation
  • [(a[0],a[1])] and [(a[-2],a[-1])], 2-tuples for particular cases (first and last numbers of list)

Upvotes: 2

Robᵩ
Robᵩ

Reputation: 168626

You can start with a solution that iterates through the indexes of the list, like so:

def sum_neighbours1(a_list):
    result = []
    for i in range(len(a_list)):
        if i == 0:
            result.append(a_list[i] + a_list[i+1])
        elif i == len(a_list)-1:
            result.append(a_list[i-1] + a_list[i])
        else:
            result.append(a_list[i-1] + a_list[i] + a_list[i+1])
    return result

print(sum_neighbours1([10,20,30,40,50]))

Or, you can build three distinct lists: the original list, the list of left-hand neighbors, and the list of right-hand neighbors. We have to put 0 at the front or rear of the auxiliary lists. Each of the lists must be at least as long as the original list.

Zip the three lists together, and add them:

def sum_neighbours2(a_list):
    priors = [0] + a_list
    subsequents = a_list[1:] + [0]
    return map(sum, zip(priors, a_list, subsequents))

Note that I used the functional notation map(sum, data), but I could have used a list conprehension just as easily:

def sum_neighbours3(a_list):
    priors = [0] + a_list
    subsequents = a_list[1:] + [0]
    return [p+a+s for p,a,s in zip(priors, a_list, subsequents)]

And, if I were eager to make the result a single expression (for example, if it had to fit in a lambda expression), here that is:

def sum_neighbours4(a_list):
    return [
        left + a + right
        for left, a, right in zip(
            [0] + a_list,
            a_list,
            a_list[1:] + [0])
    ]

Upvotes: 3

willwolfram18
willwolfram18

Reputation: 1887

You'll probably want a for i in range loop, and indexing directly into the array so you can look at the element that is at i+1 and i-1 indexes (making sure to check that your +/- 1 isn't going outside the bounds of the array).

Upvotes: -1

Related Questions