2012-10-11 51 views
-1

問題:編號,找到平均周圍

給定一個列表編號的listA,寫,作爲listA具有相同數量的元素,生成一個新的列表listB的程序,例如,在新的每一個元素列表是其鄰居和自己在原始列表中的平均值。

例如,如果listA = [5, 1, 3, 8, 4]listB = [3.0, 3.0, 4.0, 5.0, 6.0],其中:

(5 + 1)/2 = 3.0 
(5 + 1 + 3)/3 = 3.0 
(1 + 3 + 8)/3 = 4.0 
(3 + 8 + 4)/3 = 5.0 
(8 + 4)/2 = 6.0 

這樣我就可以拿到第一部分,最後一部分,因爲他們只用2號處理,但對於中間部分我不能讓它。我的循環是錯誤的,但我不確切地知道。這是我迄今爲止。

listA= [5,1,3,8,4] 

N=len(listA) 
print(listA) 

listB=[] 
listB.append((listA[0]+listA[1])/2) 

y=0 
x=1 
while x in listA: 
    y=((listA[x-1] + list[x] + list[x+1])/3) 
    listB.append(y) 
y=y+1 

listB.append((listA[-1]+listA[-2])/2) 

print(listB) 
+3

這看起來像家庭作業,所以我問你是否覆蓋了切片。這是使用列表分片的主要候選者。 –

+0

我認爲我們已經過去了,當你在列表中使用:是不是? –

+1

這是正確的,當索引列表時,括號內有冒號。 –

回答

0
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] 

或使用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] 
+0

我不認爲我們學到了拉鍊。 zip的確切含義 –

+0

你也可以用'lambda'添加一個'map'來生成最終的列表。儘管這對於一個新的程序員來說並不是很有說服力。 –

+0

@atmatm閱讀[zip here](http://docs.python.org/library/functions.html#zip) –

0
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 list 
for i in range(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))) 
0

能使用arcpy.AverageNearestNeighbor_stats

否則,如果你喜歡的循環:

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])) 
2

你可以做到這一點使用迭代器,而無需求助於通過指數循環:

import itertools 

def neighbours(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 in zip(before, items, after): 
     yield [value for value in (a, b, c) if value is not fill] 

使用像這樣:

>>> 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] 

那麼如何工作的呢?我們創建了一些額外的迭代器 - 用於之前和之後的值。我們使用itertools.chain分別爲開始和結束添加額外值,以便我們在正確的時間獲得正確的值(並且不會耗盡項目)。然後,我們將稍後的項目放在一個上,將它放在正確的位置,然後循環,返回不是None的值。這意味着我們可以以非常自然的方式循環。

請注意,這需要一個列表,因爲迭代器將被耗盡。如果你需要對一個迭代懶洋洋地工作,下面的示例使用itertools.tee()做的工作:

def neighbours(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 in zip(before, i, after): 
     yield [value for value in (a, b, c) if value is not fill] 
+0

我見過很多很棒的答案。只是想說你太棒了! –

+0

@BlaXpirit乾杯。 –

0

看起來你已經有了正確的想法。你的代碼有點難以遵循,試着在未來嘗試使用更多的描述性變量名稱:)它使每一個變得更容易。

這裏是我的快速和骯髒的解決方案:

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) 

我選擇了一個for循環,而不是一個while。這並沒有太大的區別,但我覺得語法更容易遵循。

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.) 

所以,如果我們的指數是0,我們在開始的時候,所以我們增加了當期的指數,0的值,下一個最高1,平均它,並將它添加到我們的產量名單。

如果我們的索引等於出列表的長度-1(我們使用-1,因爲列表索引從0開始,而長度不是-1沒有-1,我們會得到一個IndexOutOfRange錯誤。)我們知道我們在最後一個元素上。因此,我們取這個位置的值,將它加到列表中前一位置的值上,最後將這些數字的平均值附加到輸出列表中。

else: 
     outputList.append((listOfNums[i-1] + 
         listOfNums[i] + 
         listOfNums[i+1])/3.) 

最後,所有的其他情況下,我們僅僅是當前索引處搶的價值,而那些正上方和下方,然後追加平均結果我們的輸出列表。