1

Possible Duplicate:
iterate through pairs of items in python list

I have a list and i want to create another one which will encompasses sequent groups of item of the first one based one sliding-window parameter and the size of each group. i.e if the parameter:

a = ["a" ,"b" ,"c" ,"d" ,"e" ,"f"]

and sliding-window=1 and size =2 then i want b as:

b= [(a,b),(b,c),(c,d),(d,e),(e,f)]

the sliding window is for deciding the index of the next tuple.Each time the list would traversed by 1.I.e: If the sliding window was 2 then i would have: b= [(a,b),(c,d),(e,f)]

i am looking for a pythonic-way of achieving this.

Community
  • 1
  • 1
curious
  • 1,524
  • 6
  • 21
  • 45
  • 1
    an ugly piece of code holding each time the index, increasing until size in the first loop for constructing the first tuple and then increase the initial index by the size of the window and so on. There is sth with map and lambda that will make it much more pretty i guess – curious Feb 27 '12 at 11:17

5 Answers5

4

This is one way:

def group(l, window, size):
    return [l[index:index + size] for index in xrange(0, len(l) - 1, window)]

DEMO

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • Though you may want to make it a generator instead of a comprehension list, since you are using xrange. – Bite code Feb 27 '12 at 18:51
  • @e-satis: That's an option, but I just didn't want to have a list of numbers that I don't need otherwise in memory. – Felix Kling Feb 27 '12 at 19:39
  • No, I meant turn [] into (). So you don't have a list at all in memory unless the user explicitly ask for it. – Bite code Feb 28 '12 at 12:15
2

From the Python documentation:

from itertools import tee, izip, islice

def pairwise(iterable, size=2, slide=1):
    iters = [islice(it, i, None, slide) for i, it in enumerate(tee(iterable, size))]
    return izip(*iters)

Demo :P Timeit says:

In [58]: timeit pairwise(xrange(1000))
100000 loops, best of 3: 4.6 us per loop
Gandaro
  • 3,427
  • 1
  • 17
  • 19
  • How would this work for `sliding-window = 2` and `size = 4`? – Felix Kling Feb 27 '12 at 11:28
  • What do you mean by sliding window? I fixed it to use `n` as size. – Gandaro Feb 27 '12 at 11:32
  • I edit my answer for the sliding window. – curious Feb 27 '12 at 11:38
  • It seems you have not read the question carefully enough. – Felix Kling Feb 27 '12 at 11:39
  • @FelixKling The information about the sliding window was not in the question when I wrote this answer … – Gandaro Feb 27 '12 at 11:42
  • @curious I updated my answer so it can handle the `slide` parameter now. – Gandaro Feb 27 '12 at 11:45
  • It was always in the first paragraph: *I have a list and i want to create another one which will encompasses sequent groups of item of the first one based one **sliding-window parameter** and the **size of each group***. Then there is an example for `window=1` and `size=2`. Just saying, no worries, we are only human. – Felix Kling Feb 27 '12 at 11:49
  • @FelixKling I have read the text, but I did not understand what was meant by that, so I left it out for that moment. – Gandaro Feb 27 '12 at 11:55
2

You could try like this :

def slice(initial_list, length):
    return [ initial_list[i:i+length] for i in xrange(len(initial_list)-1)]

That would give :

a = ["a" ,"b" ,"c" ,"d" ,"e" ,"f"]
print slice(a, 2)
>>> [['a', 'b'], ['b', 'c'], ['c', 'd'], ['d', 'e'], ['e', 'f']]
Cédric Julien
  • 78,516
  • 15
  • 127
  • 132
0

See itertools recipes.

from itertools import tee, izip
def pairwise(iterable):
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

for v, w in pairwise(a):
    (...)
Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
0

Here is the same one with @Secator suggested without using itertools

i = iter(a)
next(i)
result = zip(a,i)
yilmazhuseyin
  • 6,442
  • 4
  • 34
  • 38