【发布时间】:2011-10-23 07:37:37
【问题描述】:
这更多的是优雅和性能的问题,而不是“根本怎么做”,所以我只展示代码:
def iterate_adjacencies(gen, fill=0, size=2, do_fill_left=True,
do_fill_right=False):
""" Iterates over a 'window' of `size` adjacent elements in the supploed
`gen` generator, using `fill` to fill edge if `do_fill_left` is True
(default), and fill the right edge (i.e. last element and `size-1` of
`fill` elements as the last item) if `do_fill_right` is True. """
fill_size = size - 1
prev = [fill] * fill_size
i = 1
for item in gen: # iterate over the supplied `whatever`.
if not do_fill_left and i < size:
i += 1
else:
yield prev + [item]
prev = prev[1:] + [item]
if do_fill_right:
for i in range(fill_size):
yield prev + [fill]
prev = prev[1:] + [fill]
然后问:是否已经有这样的功能?如果不能,您能否以更好(即更整洁和/或更快速)的方式做同样的事情?
编辑:
结合@agf、@FogleBird、@senderle 的答案的想法,得到的一段看起来有点整洁的代码是:
def window(seq, size=2, fill=0, fill_left=True, fill_right=False):
""" Returns a sliding window (of width n) over data from the iterable:
s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...
"""
ssize = size - 1
it = chain(
repeat(fill, ssize * fill_left),
iter(seq),
repeat(fill, ssize * fill_right))
result = tuple(islice(it, size))
if len(result) == size: # `<=` if okay to return seq if len(seq) < size
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
【问题讨论】:
-
您可能想更详细地解释一下这对文字有什么作用。
-
您能否提供样本输入和预期输出的样本?更容易理解你的函数在做什么。
-
运行代码并查看比从文档字符串中弄清楚要快,因为措辞不是很清楚,所以我建议他把它写得更清楚。
-
@HoverHell - 非常非常好。您应该将其作为答案发布并接受。我将如何以不同的方式表达文档字符串?我会把它分解成几个简短的陈述句来描述它的作用和每个论点。
-
@HoverHell: 1) 是的,请发布您的新代码作为答案。 2)This question and its answer解释如何在numpy中创建滚动窗口。
标签: python