Using List Comprehensions in Python to Create a 2D List Sorted by Predefined Values

Viewed 75

I have a function number_sort() which needs to return a 2d list with 4 lists inside. Function needs to sort the numbers given by being between 0-12, 13-25, 26-38 and 39-51 which looks like:

Given: [2, 2, 3, 4, 1, 13, 15, 51, 10, 15, 28]

Returned: [[1, 2, 2, 3, 4, 10], [13, 15, 15], [28], [51]]

I tried doing it with list comprehension.

def number_sort(cards: list):
    return [[item for item in cards if i * 13 <= item <= (i * 12 + 1)] for i in range(4)]

But when I give the exact example list given above, It returns [[1], [13], [], []]

Can someone tell me what am I doing wrong and how can I fix it?

3 Answers

IIUC, you want to groupby using 13 as floor divider:

from itertools import groupby

[list(g) for _, g in groupby(sorted(l), key=lambda x: x//13)]

Output:

[[1, 2, 2, 3, 4, 10], [13, 15, 15], [28], [51]]

There is a dynamic way you can write your code by setting constant 13.

def number_sort(cards: list):
    const = 13
    mx = round(max(data) / const)
    struct = [[] for i in range(mx)]
    for i in cards:
        struct[i // const].append(i)
    return struct

Here's a table of your bounds:

i | 13i | 12i+1
--+-----+------
0 |. 0  |   1
1 | 13  |  13
2 | 26  |  25
3 | 39  |  37

You can't have the upper bound increase in steps of 12 while the lower bound increases in steps of 13. The correct condition is

13 * i < item <= 13 * (i + 1)
Related