给定n和m的重叠迭代没有使用len()

时间:2015-04-27 13:09:33

标签: python python-3.x iterable

我试图在python中创建一个重叠函数,它接受任何iterable,一个int n ,一个int m (默认值为1)作为参数,并生成 n 值的列表:

  1. 第一个列表包含第一个 n 值;
  2. 每个后续列表都会删除前一个列表中的第一个 m
  3. 从迭代器添加下一个 m 值,直到返回列表中的 n 值少于 n
  4. 示例:

    for i in overlap('abcdefghijk',4,2):
        print(i,end=' ')
    

    ['a','b','c','d']['c','d','e','f']的输出为['e','f','g','h']['g','h',i','j']n=4m=2。在这种情况下,如果函数是这样的:

    def overlap(iterable, n, m=1)
    

    如何做到这一点?我面临的主要问题是当小于 n 值时如何停止。

    当前代码:anmol_uppal's solution的分数。

    def hide(iterable):
        for v in iterable:
            yield v
    
    def overlap(word, n, m):
        start = 0
        while(start+n < len(word)):
            yield list(word[start:start+n])
            start += m
    
    if __name__ == '__main__':   
        for i in overlap('abcdefghijk',3,2): 
            print(i, end=' ')
        print()
        for i in overlap(hide('abcdefghijk'),3,2): 
            print(i, end=' ')
        print()
    

    但问题是我们不能将len()用于生成器。

    我尝试过这段代码,但我不知道为什么它会给第二个测试用例带来意想不到的结果

    def hide(iterable):
        for v in iterable:
            yield v
    
    def window(seq, size, step=1):
        iters = [iter(seq) for i in range(size)]
        [next(iters[i]) for j in range(size) for i in range(-1, -j-1, -1)]
        while(True):
            yield [next(i) for i in iters]
            [next(i) for i in iters for j in range(step-1)]
    
    if __name__ == '__main__':
        for i in window('abcdefghijk', 3, 2): 
            print(i, end=' ')
        print()
        for i in window(hide('abcdefghijk'), 3, 2): 
            print(i, end=' ')
        print()
    

1 个答案:

答案 0 :(得分:1)

def overlap(word, n,m):
    ans = []
    start = 0
    while(start+n<len(word)):
        ans.append(list(word[start:start+n]))
        start+=m

    return ans


>>> print overlap("abcdefghijk", 4, 2)
>>> [['a', 'b', 'c', 'd'], ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h'], ['g', 'h', 'i', 'j']]
>>> print overlap("abcdefghi", 4, 2)
>>> [['a', 'b', 'c', 'd'], ['c', 'd', 'e', 'f'], ['e', 'f', 'g', 'h']]

Also if you would like to yield the results instead of returning them,then you can use the following simpler version:

def overlap(word, n,m):
    start = 0
    while(start+n<len(word)):
        yield list(word[start:start+n])
        start+=m

for i in overlap("abcdefghijk", 4, 2):
    print (i,end = " ")

To make it work with the hide() function you need to convert it to string first, so:

for i in overlap("".join(hide("abcdefghijk")),3, 2): 
    print i