在Python

问题描述:

推拉窗我用我的滑动windoe如下因素著名代码通过标记化的文本文档:在Python

def window(fseq, window_size): 
    "Sliding window" 
    it = iter(fseq) 
    result = tuple(islice(it, 0, window_size, round(window_size/4))) 
    if len(result) == window_size: 
     yield result 
    for elem in it: 
     result = result[1:] + (elem,) 
     result_list = list(result) 
     yield result_list 

时,我想打电话给我的功能与窗口尺寸小于6时,一切正常,但是当我增加它,文本的开始被切断。 例如:

c=['A','B','C','D','E', 'F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'] 
print(list(window(c, 4))) 
print(list(window(c, 8))) 

输出:

[('A', 'B', 'C', 'D'), ['B', 'C', 'D', 'E'], ['C', 'D', 'E', 'F'], ['D', 'E', 'F', 'G'], ['E', 'F', 'G', 'H'], ['F', 'G', 'H', 'I'],... 

[['C', 'E', 'G', 'I'], ['E', 'G', 'I', 'J'], ['G', 'I', 'J', 'K'], ['I', 'J', 'K', 'L'], ['J', 'K', 'L', 'M']... 

有什么不对?为什么在第一个输出中第一个元素是在圆括号内?

我的预期print(list(window(c, 8)))输出是:

[['A','B','C', 'D', 'E', 'F','G','H'], ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['E', 'F', 'G', 'H', 'I', 'K', 'L', 'M']... 
+0

你从哪里得到这个代码?它与[Python中的滚动或滑动窗口迭代器](http://*.com/q/6822725) –

+0

上的解决方案大不相同。我刚刚根据islise文档https:// docs添加了start point和te step。 python.org/2/library/itertools.html#itertools.islice – Polly

+0

但*为什么*?你不需要步长。把它设置为1. –

你的版本不正确。它增加了一个第四参数(步长)与islice()功能限制所采取的第一切片多大将是:

result = tuple(islice(it, 0, window_size, round(window_size/4))) 

对于45round(window_size/4)产生1,默认步长。但是对于较大的值,这会产生一个步长,以保证从第一个窗口中省略值,因此下一个测试len(result) == window_size保证是错误的。

删除该步长参数,您将再次返回第一个窗口。另见Rolling or sliding window iterator in Python

第一个结果是'圆括号',因为它是一个元组。如果您想要一个列表,请在代码中使用list()而不是tuple()

如果你想让你的窗口以大于1的步长滑动,你不应该改变初始窗口。在迭代时,您需要从窗口中添加并删除step大小元素。这是一个while循环更容易做到:

def window_with_larger_step(fseq, window_size): 
    """Sliding window 

    The step size the window moves over increases with the size of the window. 
    """ 
    it = iter(fseq) 
    result = list(islice(it, 0, window_size)) 
    if len(result) == window_size: 
     yield result 
    step_size = max(1, int(round(window_size/4))) # no smaller than 1 
    while True: 
     new_elements = list(islice(it, step_size)) 
     if len(new_elements) < step_size: 
      break 
     result = result[step_size:] + list(islice(it, step_size)) 
     yield result 

这增加step_size元素的运行结果,除去从一开始step_size元素,以保持窗口大小均匀。

演示:

>>> print(list(window_with_larger_step(c, 6))) 
[['A', 'B', 'C', 'D', 'E', 'F'], ['C', 'D', 'E', 'F', 'I', 'J'], ['E', 'F', 'I', 'J', 'M', 'N'], ['I', 'J', 'M', 'N', 'Q', 'R'], ['M', 'N', 'Q', 'R', 'U', 'V'], ['Q', 'R', 'U', 'V', 'Y', 'Z']] 
>>> print(list(window_with_larger_step(c, 8))) 
[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'], ['C', 'D', 'E', 'F', 'G', 'H', 'K', 'L'], ['E', 'F', 'G', 'H', 'K', 'L', 'O', 'P'], ['G', 'H', 'K', 'L', 'O', 'P', 'S', 'T'], ['K', 'L', 'O', 'P', 'S', 'T', 'W', 'X'], ['O', 'P', 'S', 'T', 'W', 'X']] 
>>> print(list(window_with_larger_step(c, 10))) 
[['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'], ['D', 'E', 'F', 'G', 'H', 'I', 'J', 'N', 'O', 'P'], ['G', 'H', 'I', 'J', 'N', 'O', 'P', 'T', 'U', 'V'], ['J', 'N', 'O', 'P', 'T', 'U', 'V', 'Z']]