user7654132
user7654132

Reputation: 123

Python for loop iterate in stepsize 3

This might be a simple problem, but I seem to have spent too much time on it... My problem consist of creating a for loop that iterates through a list.

For each iteration should three elements be extracted => those being i, i+1 and i+2. But for some reason am I not able to iterate through the list without getting out of index or something like that?..

The way I currently iterating is as so:

        for i in xrange(0,len(data_train_output_full)-1,3):
            data = np.array([data_train_output_full[i],data_train_output_full[i+1],data_train_output_full[i+2]])
            data_train_output.append(data)

And the error message I am getting is:

IndexError: index 278 is out of bounds for axis 0 with size 278

Upvotes: 2

Views: 1512

Answers (3)

DevLounge
DevLounge

Reputation: 8437

I came up with this alternate solution:

def by_n(a_list, n):
    for i in xrange(0, len(a_list), n): 
        yield a_list[i:i+n]

data_train_output = [np.array(_) for _ in by_n(data_train_output_full, 3)]

# or

data_train_output = list(map(np.array, by_n(data_train_output_full, 3))

Upvotes: 0

Blckknght
Blckknght

Reputation: 104762

Your code doesn't work because the stop value you're giving to xrange is not correct. Since you're checking two indexes after the highest one provided by xrange, you need to subtract two from the length of the input sequence (len(data_train_output_full)-2 instead of -1).

There's also an itertools recipe for this kind of iteration:

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

If your list might be uneven and you want the last values to be skipped instead of padded, you can use itertools.izip instead of itertools.izip_longest.

Upvotes: 1

juanpa.arrivillaga
juanpa.arrivillaga

Reputation: 96172

You can always write a quick generator for this, using itertools.islice ideally.

In [1]: x = list(range(28))

In [2]: def by_triples(iterable):
    ...:     it = iter(iterable)
    ...:     triple = tuple(itertools.islice(it, 3))
    ...:     while triple:
    ...:         yield triple
    ...:         triple = tuple(itertools.islice(it, 3))
    ...:
    ...:

In [3]: import itertools

In [4]: for trip in by_triples(x):
    ...:     print(trip)
    ...:
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9, 10, 11)
(12, 13, 14)
(15, 16, 17)
(18, 19, 20)
(21, 22, 23)
(24, 25, 26)
(27,)

Upvotes: 0

Related Questions