假设我有一个Python数组a=[3, 5, 2, 7, 5, 3, 6, 8, 4]
.我的目标是一次遍历这个数组3个元素,返回三个元素中前2个的平均值.
使用上面的数组,在我的迭代步骤中,前三个元素是[3, 5, 2]
,前两个元素的平均值是4.接下来的三个元素是[5, 2, 7]
,前2个元素的平均值是6.接下来的三个元素是[2, 7, 5]
和平均值前两个元素再次是6. ...
因此,上述数组的结果将是[4, 6, 6, 6, 5.5, 7, 7]
.
编写这样一个函数最好的方法是什么?
fos*_*ock 14
您可以使用列表的某些奇特切片来操作元素的子集.只需抓住每个三元素子列表,排序以找到前两个元素,然后找到简单平均值(aka.mean)并将其添加到结果列表中.
def get_means(input_list):
means = []
for i in xrange(len(input_list)-2):
three_elements = input_list[i:i+3]
sum_top_two = sum(three_elements) - min(three_elements)
means.append(sum_top_two/2.0)
return means
Run Code Online (Sandbox Code Playgroud)
你可以看到你的示例输入(和期望的结果),如下所示:
print(get_means([3, 5, 2, 7, 5, 3, 6, 8, 4]))
# [4.0, 6.0, 6.0, 6.0, 5.5, 7.0, 7.0]
Run Code Online (Sandbox Code Playgroud)
还有其他一些很好的答案可以进入更多性能导向的答案,包括使用生成器避免大内存列表的答案:https://stackoverflow.com/a/49001728/416500
Maa*_*bré 12
我相信将代码分为两部分.这里将获得滑动窗口,获得前2个元素,并计算平均值.最干净的方法是使用发电机
使用evamicur的答案略有不同tee
,islice
并zip
创建窗口:
def windowed_iterator(iterable, n=2):
iterators = itertools.tee(iterable, n)
iterators = (itertools.islice(it, i, None) for i, it in enumerate(iterators))
yield from zip(*iterators)
windows = windowed_iterator(iterable=a, n=3)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)[(3, 5, 2), (5, 2, 7), (2, 7, 5), (7, 5, 3), (5, 3, 6), (3, 6, 8), (6, 8, 4)]
计算你可以使用其他答案中使用的任何方法的2个最高值的平均值,我认为heapq
on是最清楚的
from heapq import nlargest
top_n = map(lambda x: nlargest(2, x), windows)
Run Code Online (Sandbox Code Playgroud)
或者等价的
top_n = (nlargest(2, i) for i in windows)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)[[5, 3], [7, 5], [7, 5], [7, 5], [6, 5], [8, 6], [8, 6]]
from statistics import mean
means = map(mean, top_n)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)[4, 6, 6, 6, 5.5, 7, 7]
以下代码可满足您的需求:
[sum(sorted(a[i:i + 3])[-2:]) / 2 for i in range(len(a) - 2)]
Run Code Online (Sandbox Code Playgroud)
鉴于你的a=[3, 5, 2, 7, 5, 3, 6, 8, 4]
回报:
[4.0, 6.0, 6.0, 6.0, 5.5, 7.0, 7.0]
Run Code Online (Sandbox Code Playgroud)
itertools
有一个简洁的配方,可以从任何可迭代的项目中提取项目,而不仅仅是可索引的.您可以稍微调整它以提取三胞胎:
def tripletwise(iterable):
a, b, c = itertools.tee(iterable, 3)
next(b, None)
next(itertools.islice(c, 2, 2), None)
return zip(a, b, c)
Run Code Online (Sandbox Code Playgroud)
使用它,您可以简化迭代所有三元组:
def windowed_means(iterable):
return [
(sum(window) - min(window)) / 2.0
for window in tripletwise(iterable)
]
Run Code Online (Sandbox Code Playgroud)