0

質問:

数値のリストが与えられたとき、と同じ数の要素を持つlistA新しいリストを生成するプログラムを作成して、新しいリストの各要素が元のリストの隣接要素とそれ自体の平均になるようにします。listBlistA

たとえば、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)
4

5 に答える 5

3

インデックスをループする必要なく、イテレータを使用してこれを行うことができます。

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]

では、これはどのように機能するのでしょうか。before と after の値のために、追加のイテレータをいくつか作成します。itertools.chain適切なタイミングで適切な値を取得できるようにするため (そして項目が不足しないようにするため)、最初と最後にそれぞれ追加の値を追加するために使用します。次に、後の項目を 1 つ進めて正しい位置に配置し、ループして、 でない値を返します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]
于 2012-10-11T14:36:39.280 に答える
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]))
于 2012-10-11T14:34:51.940 に答える
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]
于 2012-10-11T14:26:35.203 に答える
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)))
于 2012-10-11T14:30:34.633 に答える
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)):

入力リストの長さを繰り返すループを作成します。

次に、リストの最初と最後という 2 つの「特別な」ケースを扱います。

    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、平均して、出力リストに追加します。

インデックスが out リストの長さ - 1 に等しい場合 (リストは 0 からインデックス付けされるため、-1 を使用しますが、長さはそうではありません。-1 がないと、IndexOutOfRange エラーが発生します)。最後の要素。したがって、その位置の値を取得し、それをリスト内の前の位置の値に追加し、最後にそれらの数値の平均を出力リストに追加します。

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

最後に、他のすべてのケースでは、現在のインデックスとそのすぐ上と下の値を取得し、平均化した結果を出力リストに追加します。

于 2012-10-11T14:39:20.830 に答える