Numbers In A List, Find Average Of Surroundings
Solution 1:
You can do this using iterators without having to resort to looping through indices:
import itertools
defneighbours(items, fill=None):
before = itertools.chain([fill], items)
after = itertools.chain(items, [fill]) #You could use itertools.zip_longest() later instead.next(after)
for a, b, c inzip(before, items, after):
yield [value for value in (a, b, c) if value isnot fill]
Used like so:
>>>items = [5, 1, 3, 8, 4]>>>[sum(values)/len(values) for values in neighbours(items)]
[3.0, 3.0, 4.0, 5.0, 6.0]
So how does this work? We create some extra iterators - for the before and after values. We use itertools.chain
to add an extra value to the beginning and end respectively, in order to allow us to get the right values at the right time (and not run out of items). We then advance the later item on one, to put it in the right position, then loop through, returning the values that are not None
. This means we can just loop through in a very natural way.
Note that this requires a list, as an iterator will be exhausted. If you need it to work lazily on an iterator, the following example uses itertools.tee()
to do the job:
defneighbours(items, fill=None):
b, i, a = itertools.tee(items, 3)
before = itertools.chain([fill], b)
after = itertools.chain(a, [fill])
next(a)
for a, b, c inzip(before, i, after):
yield [value for value in (a, b, c) if value isnot fill]
Solution 2:
list_a = [5, 1, 3, 8, 4]
# Start list_b with the special case first element
list_b = [sum(list_a[:1]) / 2.0]
# Iterate over each remaining index in the listfor i inrange(1, len(list_a - 1)):
# Get the slice of the element and it's neighbors
neighborhood = list_a[i-1:i+1]
# Add the average of the element and it's neighbors# have to calculate the len of neighborhood to handle# last element special case
list_b.append(sum(neighborhood) / float(len(neighborhood)))
Solution 3:
Could use arcpy.AverageNearestNeighbor_stats
Otherwise, if you like loops:
import numpy as np
listA= [5,1,3,8,4]
b = []
for r in xrange(len(listA)):
if r==0 or r==len(listA):
b.append(np.mean(listA[r:r+2]))
else:
b.append(np.mean(listA[r-1:r+2]))
Solution 4:
It looks like you've got the right idea. Your code is a little tough to follow though, try using more descriptive variable names in the future :) It makes it easier on every one.
Here's my quick and dirty solution:
def calcAverages(listOfNums):
outputList = []
for i in range(len(listOfNums)):
if i == 0:
outputList.append((listOfNums[0] + listOfNums[1]) / 2.)
elif i == len(listOfNums)-1:
outputList.append((listOfNums[i] + listOfNums[i-1]) / 2.)
else:
outputList.append((listOfNums[i-1] +
listOfNums[i] +
listOfNums[i+1]) / 3.)
return outputList
if __name__ == '__main__':
listOne = [5, 1, 3, 8, 4, 7, 20, 12]
print calcAverages(listOne)
I opted for a for
loop instead of a while
. This doesn't make a big difference, but I feel the syntax is easier to follow.
for i in range(len(listOfNums)):
We create a loop which will iterate over the length of the input list.
Next we handle the two "special" cases: the beginning and end of the list.
if i == 0:
outputList.append((listOfNums[0] + listOfNums[1]) / 2.)
elif i == len(listOfNums)-1:
outputList.append((listOfNums[i] + listOfNums[i-1]) / 2.)
So, if our index is 0, we're at the beginning, and so we add the value of the currect index, 0
, and the next highest 1
, average it, and append it to our output list.
If our index is equal to the length of out list - 1 (we use -1 because lists are indexed starting at 0, while length is not. Without the -1, we would get an IndexOutOfRange error.) we know we're on the last element. And thus, we take the value at that position, add it to the value at the previous position in the list, and finally append the average of those numbers to the output list.
else:
outputList.append((listOfNums[i-1] +
listOfNums[i] +
listOfNums[i+1]) / 3.)
Finally, for all of the other cases, we simply grab the value at the current index, and those immediately above and below it, and then append the averaged result to our output list.
Solution 5:
In [31]: lis=[5, 1, 3, 8, 4]
In [32]: new_lis=[lis[:2]]+[lis[i:i+3] for i in range(len(lis)-1)]
In [33]: new_lis
Out[33]: [[5, 1], [5, 1, 3], [1, 3, 8], [3, 8, 4], [8, 4]]
#now using sum() ans len() on above list and using a list comprehension
In [35]: [sum(x)/float(len(x)) for x in new_lis]
Out[35]: [3.0, 3.0, 4.0, 5.0, 6.0]
or using zip()
:
In [36]: list1=[lis[:2]] + zip(lis,lis[1:],lis[2:]) + [lis[-2:]]
In [37]: list1
Out[37]: [[5, 1], (5, 1, 3), (1, 3, 8), (3, 8, 4), [8, 4]]
In [38]: [sum(x)/float(len(x)) for x in list1]
Out[38]: [3.0, 3.0, 4.0, 5.0, 6.0]
Post a Comment for "Numbers In A List, Find Average Of Surroundings"