8

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 . . .

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
O.rka
  • 29,847
  • 68
  • 194
  • 309
  • possible duplicate of [Python split string in moving window](http://stackoverflow.com/questions/7636004/python-split-string-in-moving-window) – Jon-Eric Dec 07 '11 at 00:12
  • 5
    Dude... are you going to post the same question every 8 hours? :o – mac Dec 07 '11 at 08:40
  • My bad i thought i would of been able to delete the other – O.rka Dec 07 '11 at 10:08
  • It would still have been wrong: if you ask a question and you don't get answers chances are: (1) you formulated it poorly [ → edit it ] - (2) it's a difficult question [ → answer yourself some question, get reputation points and place a bounty on it ]. Reposting to gain attention is not a welcome behaviour on SO (although I am positive you did not do it with the intention of doing any harm!) :) – mac Dec 07 '11 at 10:12

6 Answers6

17

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']
Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
  • 2
    Shall we use range instead of xrange for more compatibility with python 3 ? – Clement H. Jun 18 '19 at 09:25
  • @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](https://pypi.org/project/six/). – Cédric Julien Jun 18 '19 at 10:10
6

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
eumiro
  • 207,213
  • 34
  • 299
  • 261
  • 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 – O.rka Apr 14 '16 at 14:45
  • In python3, `xrange` is now just `range` – neuron Dec 01 '21 at 16:05
2

Use zip function in one line code:

  [ "".join(j) for j in zip(*[fseq[i:] for i in range(window_size)])]
risent
  • 136
  • 1
  • 4
1
def window(fseq,fn):
    alpha=[fseq[i:i+fn] for i in range(len(fseq)-(fn-1))]
    return alpha
O.rka
  • 29,847
  • 68
  • 194
  • 309
0
>>>def window(data, win_size):
...    tmp = [iter(data[i:]) for i in range(win_size)]
...    return zip(*tmp)
>>> a = [1, 2, 3, 4, 5, 6]
>>> window(a, 3)
>>>[(1,2,3), (2,3,4), (3,4,5), (4,5,6)]
Mass Zhou
  • 349
  • 3
  • 6
0

I don't know what your input or expected output are, but you cannot mix yield and return in one function. change return to yield and your function will not throw that error again.

def window(fseq, window_size=5):
    ....
        final.append(tentative_string)
    yield final
Serdalis
  • 10,296
  • 2
  • 38
  • 58