Bruno Cerk
Bruno Cerk

Reputation: 355

Iterate though list on each for loop iteration

I'm working on the following code:

mylist = [1,2,3,4,5,6,7,8,9,10.....]
for x in range(0, len(mylist), 3):
    value = mylist[x:x + 3]
    print(value)

Basically, I'm taking 3 items in mylist at a time, the code is bigger than that, but I'm doing a lot of things with them returning a value from it, then it takes the next 3 items from mylist and keep doing it till the end of this list.

But now I have a problem, I need to identify each iteration, but they follow a rule:

The first loop are from A, the second are from B and the third are from C. When it reaches the third, it starts over with A, so what I'm trying to do is something like this:

mylist[0:3] are from A

mylist[3:6] are from B

mylist[6:9] are from C

mylist[9:12]are from A

mylist[12:15] are from B......

The initial idea was to implement a identifier the goes from A to C, and each iteration it jumps to the next identifier, but when it reaches C, it backs to A.

So the output seems like this:

[1,2,3] from A
[4,5,6] from B
[6,7,8] from C
[9,10,11] from A
[12,13,14] from B
[15,16,17] from C
[18,19,20] from A.....

My bad solution: Create identifiers = [A,B,C] multiply it by the len of mylist -> identifiers = [A,B,C]*len(mylist) So the amount of A's, B's and C's are the same of mylist numbers that it needs to identify. Then inside my for loop I add a counter that adds +1 to itself and access the index of my list.

mylist = [1,2,3,4,5,6,7,8,9,10.....]
identifier = ['A','B','C']*len(mylist)
counter = -1
for x in range(0, len(mylist), 3):

    value = mylist[x:x + 3]
    counter += 1
    print(value, identifier[counter])

But its too ugly and not fast at all. Does anyone know a faster way to do it?

Upvotes: 1

Views: 120

Answers (4)

David Leon
David Leon

Reputation: 1017

Based on Ignacio's answer fitted for your problem.
You can first reshape your list into a list of arrays containing 3 elements:

import pandas as pd
import numpy as np
import itertools

mylist = [1,2,3,4,5,6,7,8,9,10]
_reshaped = np.reshape(mylist[:len(mylist)-len(mylist)%3],(-1,3))

print(_reshaped)
[[1 2 3]
 [4 5 6]
 [7 8 9]]

Note that it works since your list contains multiple of 3 elements (so you need to drop the last elements in order to respect this condition, mylist[:len(mylist)-len(mylist)%3]) - Understanding slice notation
See UPDATE section for a reshape that fits to your question.

Then apply Ignacio's solution on the reshaped list

for value, iden in zip(_reshaped, itertools.cycle(('A', 'B', 'C'))):
    print(value, iden)

[1 2 3] A
[4 5 6] B
[7 8 9] C

UPDATE
You can use @NedBatchelder's chunk generator to reshape you array as expected:

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]

mylist = [1,2,3,4,5,6,7,8,9,10]

_reshaped = list(chunks(mylist, 3))
print(_reshaped)
    [[1 2 3]
     [4 5 6]
     [7 8 9]
     [10]]

Then:

for value, iden in zip(_reshaped, itertools.cycle(('A', 'B', 'C'))):
    print(value, iden)

[1 2 3] A
[4 5 6] B
[7 8 9] C
[10] A

Performances

Your solution : 1.32 ms ± 94.3 µs per loop
With a reshaped list : 1.32 ms ± 84.6 µs per loop

You notice that there is no sensitive difference in terms of performances for an equivalent result.

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798676

Cycle, zip, and unpack:

mylist = [1,2,3,4,5,6,7,8,9,10]

for value, iden in zip(mylist, itertools.cycle('A', 'B', 'C')):
    print(value, iden)

Output:

1 A
2 B
3 C
4 A
5 B
6 C
7 A
8 B
9 C
10 A

Upvotes: 4

pask
pask

Reputation: 927

You could create a Generator for the slices:

grouped_items = zip(*[seq[i::3] for i in range(3)])

Upvotes: 0

quamrana
quamrana

Reputation: 39354

You can always use a generator to iterate over your identifiers:

def infinite_generator(seq):
    while True:
        for item in seq:
            yield item

Initialise the identifiers:

identifier = infinite_generator(['A', 'B', 'C'])

Then in your loop:

print(value, next(identifier))

Upvotes: 2

Related Questions