Home > Enterprise >  3 Patterns in one for x in range(y) loop without list comprehension
3 Patterns in one for x in range(y) loop without list comprehension

Time:11-21

Instead of using 3 loops separately, I'd like to use only one loop and speed up the code.

There are 3 different patterns of range(0,150), increasing 3 per loop:

0,3,6,9...
1,4,7,10...
2,5,8,11....

My code:

fromlist = [1,2,3,4,5]
req1list = ['z','t','y']
req2list = [21,39,52]
req3list = [100,200,300]

for i in range(0,150,3):
    req1list.append(fromlist[i])
for j in range(1,150,3):
    req2list.append(fromlist[j])
for x in range(2,151,3):
    req3list.append(fromlist[x])

Note that lists are already created and there is data inside the file. Thus, I thought that list comprehension would be impossible.

Another note: please ignore the list lengths, in my file the lists are far longer and don't cause errors in [].

Is there any way that unites these 3 loops in one, and speed up the code?

CodePudding user response:

Instead of trying to perform three appends in each iteration (in one loop), you'll get faster results if you call extend instead of append. You could also use slicing to avoid comprehension:

req1list.extend(fromlist[::3])
req2list.extend(fromlist[1::3])
req3list.extend(fromlist[2::3])

And if it is important to stop at 150, add it in the slice operation:

req1list.extend(fromlist[:150:3])
# ...etc

CodePudding user response:

A slightly different approach would be to use the grouper function defined in the itertools documentation.

def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
    args = [iter(iterable)] * n
    if incomplete == 'fill':
        return zip_longest(*args, fillvalue=fillvalue)
    if incomplete == 'strict':
        return zip(*args, strict=True)
    if incomplete == 'ignore':
        return zip(*args)
    else:
        raise ValueError('Expected fill, strict, or ignore')

With this, you can write

for x, y, z in grouper(fromlist, 3):
    req1list.append(x)
    req2list.append(y)
    req3list.append(z)

(You can copy the definition of grouper from the documentation to your own code, or use the third-party more-itertools package which includes it and many more useful functions for dealing with iterators.)

  • Related