List comprehension to get a 2D list of the same values

Viewed 138

I have the following digits:

arr = [4, 5, 5, 5, 6, 6, 4, 1, 4, 4, 3, 6, 6, 3, 6, 1, 4, 5, 5, 5]

I want to create a list comprehension that will match me all the same values in a 2d array of lists like:

[[1, 1], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6]]

I tried something like:

listArr = sorted(arr)

unfortunately I don't know how to put the sorted numbers into a 2D array of lists.

4 Answers

You can create temporary dictionary to group the digits:

s = "4 5 5 5 6 6 4 1 4 4 3 6 6 3 6 1 4 5 5 5"

out = {}
for d in s.split():
    out.setdefault(d, []).append(int(d))

out = sorted(out.values())
print(out)

Prints:

[[1, 1], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6]]

If s is a list of numbers:

out = {}
for d in s:
    out.setdefault(d, []).append(d)

out = sorted(out.values())
print(out)

With itertools.groupby:

from itertools import groupby

arr = [4, 5, 5, 5, 6, 6, 4, 1, 4, 4, 3, 6, 6, 3, 6, 1, 4, 5, 5, 5]

out = [[*gr] for _, gr in groupby(sorted(arr))]

where the grouping keys are the values themselves in the sorted array and the groups are the consecutive values. [*gr] is a way to form a list out of those values, might also use list(gr) in there.

to get

>>> out

[[1, 1], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6]]
s = "4 5 5 5 6 6 4 1 4 4 3 6 6 3 6 1 4 5 5 5"
l = list(map(int, s.split()))
output = [[val] * l.count(val) for val in set(l)]

Output:

[[1, 1], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6]]

After sorting, you can use itertools.groupby.

>>> L = [4, 5, 5, 5, 6, 6, 4, 1, 4, 4, 3, 6, 6, 3, 6, 1, 4, 5, 5, 5]
>>> from itertools import groupby
>>> [list(group) for _key, group in groupby(sorted(L))]
[[1, 1], [3, 3], [4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6]]

However, it may be more efficient to sort after, like in Andrej's answer, since it would mean fewer swaps.

Related