Convert for loop to List Comprehension Python

The problem is for all the numbers (1 – 20) the highest single digit (1 – 9) of any of the numbers is divisible by.

I have a for loop as given below:

values = [[] for value in range(1, 11)]

for num in range(1, 21):
    highest = 0
    for div in range(1, 10):
        if(num % div == 0 and div > highest):
            highest = div
    
    values[highest].append(num)

The following for loop output:

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

The empty list [] that in the output can be ignored. For example:

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

I want to convert the following for loop to list comprehension, can anyone please help me.

>Solution :

Why do you need the first empty list? The solution proposed by @Olvin makes clever use of pop. You’ll have to reverse it to get what you want though.

Here a solution that might be easier to understand and gives you the result you expect:

print([ [num for num in range(1,21) if num % div == 0 and all(num % x != 0 for x in range(div + 1, 10)) ] for div in range(1,10)])

Output:

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

The use of all will generate more computing time (so will reverse in the other solution).
It’s fun to create comprehension if you want to train but loops are fine as well. And here much easier to read!

EDIT

Since so many people commented on the question and my answer I started to look closer to the problem and timed all solutions. It turns out @Olvin’s solution is the fastest and matches the speed of OP’s loop. Followed by my solution (approx. 3x slower on my machine) and @JonSG’s solution (9x slower) turns out reversing the lists is much better optimized than I thought…

Leave a Reply