2

How do I extract all n-element sequences from a list? Example:

a = [0,1,2,3,4]
assert f(a,1) == [[0],[1],[2],[3],[4]]
assert f(a,2) == [[0,1],[1,2],[2,3],[3,4]]
assert f(a,3) == [[0,1,2],[1,2,3],[2,3,4]]
assert f(a,4) == [[0,1,2,3],[1,2,3,4]]
assert f(a,5) == [[0,1,2,3,4]]

What is the fastest implementation of f?

yatu
  • 86,083
  • 12
  • 84
  • 139
Daniel Salvadori
  • 427
  • 6
  • 15
  • These are not all n-element sequences if I'm not mistaken. For example in the second assertion you are skipping a (1,3) set. If you want to achieve exactly what your example shows, it's just loops, otherwise have a look at https://stackoverflow.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n – Kacperito Feb 02 '19 at 19:04
  • 1
    Well, in case you want to achieve exactly what your example shows, you can use this: `f = lambda a, n: [a[index:index+n] for index in range(0, len(a) - n + 1)]` – Kacperito Feb 02 '19 at 19:18
  • @KacperFloriański each assert line is for a different n. The list comprehension you supplied is great. – Daniel Salvadori Feb 02 '19 at 20:08

2 Answers2

1

Here's a way you could do it using a generator function, which will yield sequential slices from the list until there are none left of the required length:

def f(x, k, i = 0):
    while len(x[i : i+k]) == k:
        yield x[i : i+k]
        i += 1

Usage

a = [0,1,2,3,4]

list(f(a, 1))
#[[0], [1], [2], [3], [4]]

list(f(a, 2))
#[[0, 1], [1, 2], [2, 3], [3, 4]]

list(f(a, 3))
#[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
yatu
  • 86,083
  • 12
  • 84
  • 139
1

Sounds like a classic zip usage

def f(a, n):
    return list(zip(*[a[i:] for i in range(n)]))
Uri Goren
  • 13,386
  • 6
  • 58
  • 110