4

I need a function that given a range, it yields all the subranges (in a list or in a tuple) of specified order. For example:

my_function((0,1,2,3,4,5), 3)

should give:

[(0,1,2),(1,2,3),(2,3,4),(3,4,5)].

Is there such a function? Or is there anything similar from which I can start? (If it works on lists it is also fine.)

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
geodude
  • 221
  • 1
  • 2
  • 7

2 Answers2

2

You can take all appropriate list slices:

r = range(6)
n = 3
for i in range(len(r) - n + 1):
    print r[i: i + n]

Output:

[0, 1, 2]
[1, 2, 3]
[2, 3, 4]
[3, 4, 5]
JuniorCompressor
  • 19,631
  • 4
  • 30
  • 57
2

You can use zip function :

>>> l=(0,1,2,3,4,5)
>>> zip(l,l[1:],l[2:])
[(0, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5)]

The following benchmark shows that using zip is faster than islice or a simple list comprehension :

:~$ python -m timeit "l=(0,1,2,3,4,5);from itertools import islice;[list(islice(l, i, i + 3)) for i in range(len(l) - 3 + 1)]"
100000 loops, best of 3: 4.47 usec per loop

:~$ python -m timeit "l=(0,1,2,3,4,5);[l[i: i + 3] for i in range(len(l) - 3 + 1)]"
1000000 loops, best of 3: 0.632 usec per loop

:~$ python -m timeit "l=(0,1,2,3,4,5);zip(l,l[1:],l[2:])"
1000000 loops, best of 3: 0.447 usec per loop

Also as says in comment for long lists and also for large slices you can use izip and islice functions from itertools module :

zip_longest(*(islice(l, i) for i in range(n))) # in python 3

izip(*(islice(l, i) for i in xrange(n))) # in python 2
Mazdak
  • 105,000
  • 18
  • 159
  • 188
  • 2
    Generalization for n-sized window: `zip(*(l[i:] for i in range(n)))` or xrange in Python 2.x. Also your benchmark is flawed because it's including import-time. – Shashank Apr 26 '15 at 18:40
  • @Shashank Yeah! also with `izip` is more efficient for longer lists! – Mazdak Apr 26 '15 at 18:44
  • Yeah for long lists and large n: `izip(*(islice(l, i) for i in range(n)))` is a memory-efficient solution. (Or just zip for Python 3) – Shashank Apr 26 '15 at 18:46
  • Oops, should be xrange for Py2.x >_< haha – Shashank Apr 26 '15 at 18:59