views:

115

answers:

3

Does Python offer a way to iterate over all "consecutive sublists" of a given list L - i.e. sublists of L where any two consecutive elements are also consecutive in L - or should I write my own?

(Example: if L = [1, 2, 3], then the set over which I want to iterate is {[1], [2], [3], [1, 2], [2,3], [1, 2, 3]}. [1, 3] is skipped since 1 and 3 are not consecutive in L.)

+2  A: 

I don't think there's a built-in for exactly that; but it probably wouldn't be too difficult to code up by hand - you're basically just looping through all of the possible lengths from 1 to L.length, and then taking all substrings of each length.

You could probably use itertools.chain() to combine the sequences for each length of substring together into a generator for all of them.

Example:

>>> a = [1,2,3,4]
>>> list(
... itertools.chain(
... *[[a[i:i+q] for q in xrange(1,len(a)-i+1)] for i in xrange(len(a))]
... )
... )
[[1], [1, 2], [1, 2, 3], [1, 2, 3, 4], [2], [2, 3], [2, 3, 4], [3], [3, 4], [4]]

If you prefer them in the increasing-length-and-then-lexographical-order sequence that you described, you'd want this instead:

itertools.chain(*[[a[q:i+q] for q in xrange(len(a)-i+1)] for i in xrange(1,len(a)+1)])
Amber
+1  A: 

This should work:

def sublists(lst):
    for sublen in xrange(1,len(lst)+1):
        for idx in xrange(0,len(lst)-sublen+1):
            yield lst[idx:idx+sublen]
job
+1  A: 

Try something like this:

def iter_sublists(l):
    n = len(l)+1
    for i in xrange(n):
        for j in xrange(i+1, n):
            yield l[i:j]

>>> print list(iter_sublists([1,2,3]))
[[1], [1, 2], [1, 2, 3], [2], [2, 3], [3]]
Tamás