Python 列表中的数字,查找周围环境的平均值

Python 列表中的数字,查找周围环境的平均值,python,list,python-3.x,Python,List,Python 3.x,问题: 给定一个数字列表listA,编写一个程序,生成一个新列表listB,其元素数量与listA相同,这样新列表中的每个元素都是原始列表中相邻元素和自身的平均值 例如,如果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 所以我可以得到第一部分,最后一

问题:

给定一个数字列表
listA
,编写一个程序,生成一个新列表
listB
,其元素数量与
listA
相同,这样新列表中的每个元素都是原始列表中相邻元素和自身的平均值

例如,如果
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)
或者使用
zip()

或者使用
zip()


可以使用arcpy.averagenearestness\u统计信息

否则,如果您喜欢循环:

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

可以使用arcpy.averagenearestness\u统计信息

否则,如果您喜欢循环:

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

您可以使用迭代器执行此操作,而无需通过索引进行循环:

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
分别在开头和结尾添加一个额外的值,以使我们能够在正确的时间获得正确的值(并且不会耗尽项目)。然后,我们将后面的项推进到一上,将其置于正确的位置,然后循环,返回非
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]

您可以使用迭代器执行此操作,而无需通过索引进行循环:

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
分别在开头和结尾添加一个额外的值,以使我们能够在正确的时间获得正确的值(并且不会耗尽项目)。然后,我们将后面的项推进到一上,将其置于正确的位置,然后循环,返回非
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]

看来你的想法是对的。不过,您的代码有点难理解,以后尝试使用更具描述性的变量名:)这会使每个变量都更容易理解

以下是我快速而肮脏的解决方案:

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)):
我们创建一个循环,它将在输入列表的长度上迭代

    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)
接下来我们处理两个“特殊”情况:列表的开头和结尾

    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
,将其平均,并将其附加到输出列表中

    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)
如果我们的索引等于out list-1的长度(我们使用-1,因为列表从0开始索引,而长度不是。如果没有-1,我们将得到一个indexoutfrange错误)。我们知道我们在最后一个元素上。因此,我们获取该位置的值,将其添加到列表中前一位置的值,最后将这些数字的平均值附加到输出列表中

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

最后,对于所有其他情况,我们只需获取当前索引处的值以及紧靠其上下的值,然后将平均结果附加到输出列表中

看来你的想法是对的。不过,您的代码有点难理解,以后尝试使用更具描述性的变量名:)这会使每个变量都更容易理解

    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)
以下是我快速而肮脏的解决方案:

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)):
我们创建一个循环,它将在输入列表的长度上迭代

    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)
接下来我们处理两个“特殊”情况:列表的开头和结尾

    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
,将其平均,并将其附加到输出列表中

    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)
如果我们的索引等于out list-1的长度(我们使用-1,因为列表从0开始索引,而长度不是。如果没有-1,我们将得到一个indexoutfrange错误)。我们知道我们在最后一个元素上。因此,我们获取该位置的值,将其添加到列表中前一位置的值,最后将这些数字的平均值附加到输出列表中

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

最后,对于所有其他情况,我们只需获取当前索引处的值以及紧靠其上下的值,然后将平均结果附加到输出列表中

这看起来像是家庭作业,所以我问你是否已经涵盖了切片。这是使用列表切片的主要候选。我想我们已经讨论过了,当你在列表中使用:时不是吗?这是正确的,当你在索引列表时在括号中有一个冒号。这看起来像是家庭作业,所以我问你是否已经讨论过切片。这是使用列表切片的主要候选方法。我想我们已经讨论过了,当您在列表中使用:时不是吗?这是正确的,当您在索引列表时,在括号中有一个冒号。您还可以添加带有
lambda的
映射
,以生成最终列表。虽然这对一个新的程序员来说不是很容易解释。你也可以添加一个带有
lambda
map
来生成最终的列表。虽然对于一个新的节目来说,这不是很好的解释
    else:
        outputList.append((listOfNums[i-1] +
                        listOfNums[i] + 
                        listOfNums[i+1]) / 3.)