[PYTHON] Divide a set of integers into cosets in one shot

For example, $ \ bmod 3 $

ns = range(30)
m = 3
list(zip(*zip(*[iter(ns)]*m)))
[(0, 3, 6, 9, 12, 15, 18, 21, 24, 27),
 (1, 4, 7, 10, 13, 16, 19, 22, 25, 28),
 (2, 5, 8, 11, 14, 17, 20, 23, 26, 29)]

Then, when divided by $ 3 $, the remainder can be divided into integers of $ 0 $, $ 1 $, and $ 2 $. If you plunge into a list that isn't a number, skip three contents into one chunk.

ls = list('abcdefghijkl')
m = 3
list(zip(*zip(*[iter(ls)]*m)))
[('a', 'd', 'g', 'j'), ('b', 'e', 'h', 'k'), ('c', 'f', 'i', 'l')]

I don't know if this notation seems cool, but let me briefly explain why it works. For example

s = list(range(12))
s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

To divide into 4 by 3 numbers

list(zip(*[iter(s)]*3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]

I think that there is a method called, which is quite famous. Actually, it is written suddenly in zip function of official tutorial.

You can use an idiom to cluster the data series into groups of length n using> zip (* [iter (s)] * n).

If you take a closer look, you'll notice that if you plunge this result into the zip function, you'll end up with a three-skip list.

list(zip(*zip(*[iter(s)]*3)))
[(0, 3, 6, 9), (1, 4, 7, 10), (2, 5, 8, 11)]

However, with this method, if you try to divide a list of 10 numbers into 3 numbers, the odd part will be truncated.

list(zip(*[iter(list(range(10)))]*3)) #9 is truncated
[(0, 1, 2), (3, 4, 5), (6, 7, 8)]

This is the specification of the zip function. To avoid this, the zip_longest function is provided in ʻitertools`.

from itertools import zip_longest
list(zip_longest(*[iter(list(range(10)))]*3)) #None enters in odd places
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None)]

Use this to update cosets as well. Finally, there is a process to remove None, but be aware that tuple is immutable. In the end, it was a set of sets, like mathematics.

from itertools import zip_longest
ns = range(50)
m = 3
[{x for x in t if x != None} for t in zip(*zip_longest(*[iter(ns)]*m))]
[{0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48},
 {1, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49},
 {2, 5, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47}]

The zip function ~~ I don't really like the name ~~, but it's deep.

Recommended Posts

Divide a set of integers into cosets in one shot
Python that merges a lot of excel into one excel
A set of script files that do wordcloud in Python3
How to combine all CSVs in a folder into one CSV
How to convert 0.5 to 1056964608 in one shot
Reversible scrambling of integers in Python
Display a list of alphabets in Python 3
Sum of variables in a mathematical model
Set the number of elements in a NumPy one-dimensional array to a power of 2 (0 padded)
Make a list in which characters are stored as one element into a string
I want to set a life cycle in the task definition of ECS