Running two for loops with different intervals simultaneously in one function

Viewed 35
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

b, c = filter_list(a)

b = [1, 3, 4, 5]
c = [2, 6, 7, 8,9]

Given list a that gets filtered by features of the elements of that list( not-relevant) and put into two different lists a, b through function filter_list .

def print_all_loop(number_list, repetition, seconds=5):
    for x in range(0, repetition):
        for i in range(len(number_list)):
            print(number_list[i])
        sleep(seconds)

The function above takes a numbers_list(b OR c), prints every element, sleeps a given amount(seconds) and repeats this a given amount of times(repetition).

Now I want to make a function that can take two lists (b AND c) and make it sleep different amounts.

The function should loop over (printing in this case all elements) both list b and c but over b every 1min and over c every 15min

Output of b every 1min and c every 15min should be:

min
1 print b [1, 3, 4, 5] and print c [2, 6, 7, 8, 9]
2 print b
3 print b
4 print b
5 print b
6 print b
7 print b
8 print b
9 print b
10 print b
11 print b
12 print b
13 print b
14 print b
15 print b [1, 3, 4, 5] and print c [2, 6, 7, 8, 9]
16 print b

Is there any other way to do this efficiently besides threading? As I would rather not use that.

Thanks in advance! If any more details are needed do ask.

1 Answers

How about this:

import asyncio


async def print_all(some_list, times, delay=5):
    for _ in range(times):
        for item in some_list:
            print(item)
        await asyncio.sleep(delay)


async def loop_lists(a, b, delay_a, delay_b, times):
    await asyncio.gather(
        print_all(a, times, delay_a),
        print_all(b, times, delay_b)
    )


async def main():
    a = [1, 3, 4, 5]
    b = ["x", "y", "z"]
    await loop_lists(a, b, 2, 1, 5)


if __name__ == '__main__':
    asyncio.run(main())

asyncio.gather runs the passed awaitables concurrently. Note that for this to work, you must use the asyncio.sleep function instead of the time.sleep function. This is because you need a point where the event loop can switch contexts, i.e. stop executing one coroutine and hop to another.

PS:

You could even generalize loop_lists to accept an arbitrary number of list-delay-pairs like so:

async def loop_lists(*list_delay_pairs, times):
    await asyncio.gather(
        *(print_all(lst, times, delay) for lst, delay in list_delay_pairs)
    )

And then call it like this:

async def main():
    a = [1, 3, 4, 5]
    b = ["x", "y", "z"]
    await loop_lists((a, 2), (b, 1), times=5)
Related