Generate a list of strings with a sliding window using itertools, yield, and iter() in Python 2.7.1?

10,493

Solution 1

You mean you want to do this ? :

a='abcdefg'
b = [a[i:i+3] for i in xrange(len(a)-2)]
print b
['abc', 'bcd', 'cde', 'def', 'efg']

Solution 2

Your generator could be much shorter:

def window(fseq, window_size=5):
    for i in xrange(len(fseq) - window_size + 1):
        yield fseq[i:i+window_size]


for seq in window('abcdefghij', 3):
    print seq


abc
bcd
cde
def
efg
fgh
ghi
hij

Solution 3

Use zip function in one line code:

  [ "".join(j) for j in zip(*[fseq[i:] for i in range(window_size)])]

Solution 4

def window(fseq,fn):
    alpha=[fseq[i:i+fn] for i in range(len(fseq)-(fn-1))]
    return alpha
Share:
10,493
O.rka
Author by

O.rka

I am an academic researcher studying machine-learning and microorganisms

Updated on June 13, 2022

Comments

  • O.rka
    O.rka about 2 years

    I'm trying to generate a sliding window function in Python. I figured out how to do it but not all inside the function. itertools, yield, and iter() are entirely new to me.

    i want to input

    a='abcdefg'
    b=window(a,3)
    print b
    ['abc','bcd','cde','def','efg']
    

    the way i got it work was

    def window(fseq, window_size=5):
        import itertools
        tentative=[]
        final=[]
        iteration=iter(fseq)
        value=tuple(itertools.islice(iteration,window_size))
        if len(value) == window_size:
            yield value
        for element in iteration:
            value = value[1:] + (element,)
            yield value
    
    a='abcdefg'
    result=window(a)
    list1=[]
    for k in result:
        list1.append(k)
    list2=[]   
    for j in list1:
        tentative=''.join(j)
        list2.append(tentative)
    print list2
    

    basically what im confused about is how to use the final value of the function inside the function?

    here is my code for the function

    def window(fseq, window_size=5):
        import itertools
        tentative=[]
        final=[]
        iteration=iter(fseq)
        value=tuple(itertools.islice(iteration,window_size))
        if len(value) == window_size:
            yield value
        for element in iteration:
            value = value[1:] + (element,)
            yield value
        for k in value:
            tentative.append(k)
        for j in tentative:
            tentative_string=''.join(j)
            final.append(tentative_string)
        return final
    
    
    
    seq='abcdefg'
    uence=window(seq)
    print uence
    

    i want it to return the joined list but when i press run it, it says "There's an error in your program * 'return' with argument inside generator"

    I'm really confused . . .

  • O.rka
    O.rka about 8 years
    this is definitely the better option. i didn't know what generators were at the time and didnt have to deal with large datasets like i do now
  • Clement H.
    Clement H. about 5 years
    Shall we use range instead of xrange for more compatibility with python 3 ?
  • Cédric Julien
    Cédric Julien about 5 years
    @ClementH. original OP was about a python2.7 installation, so, in this case, xrange was the best (for memory consumption). Yet, in python3, range would be the best solution. If you don't have too big number to iterate on, keep range everywhere, otherwise, use six.
  • neuron
    neuron over 2 years
    In python3, xrange is now just range