3

Given a list of the form:

list={{1,2,3,4,5},{6,7,8,9,10},{11,12},{13,14,15,16},{17,18,19,20,21,22,23},{24},{25,26},{27},{4}}

How can I bin each sequential set of n elements of the list together? For example, if n = 3, we would transform the above list into:

{{1,2,3,4,5,6,7,8,9,10,11,12},{13,14,15,16,17,18,19,20,21,22,23,24},{25,26,27,4}}

of length 3.

Syed
  • 52,495
  • 4
  • 30
  • 85
HStoley
  • 179
  • 6

4 Answers4

6

Let

list={{1,2,3,4,5},{6,7,8,9,10},{11,12},{13,14,15,16},
       {17,18,19,20,21,22,23},{24},{25,26},{27},{4}}

Thanks to @b.gatessucks, you could either:

 Join @@@ Partition[list, 3]

or

 Flatten /@ Partition[list, 3]

both return:

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, {25, 26, 27, 4}}

Note that depending on the initial structure of list, maybe "unexpected" results might occur, e.g. try the following (dropping the last element, i.e. {4}):

Flatten /@ Partition[Most@list, 3]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}}

Why? Most@listnow only has 8 elements, thus it is hard to partition in groups of three. By standard, Partition only returns the "full" (i.e. consisting of 3 elements) lists.

To react, you could e.g. use:

Flatten /@ Partition[Most@list, 3, 3, 1, {}]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, {25, 26, 27}}

See the documentation of Partition for more information.

Also, check out the dynP function by Mr.Wizard!

Pinguin Dirk
  • 6,519
  • 1
  • 26
  • 36
4

Try!

Partition[Flatten@#1, #2, #2, 1, {}] & @@ {list, 12}
PlatoManiac
  • 14,723
  • 2
  • 42
  • 74
2
Partition[list, 3, 3, 1, {}, Join]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
{13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24},
{25, 26, 27, 4}}

Also

BlockMap[Flatten, list,3]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
{13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24},
{25, 26, 27, 4}}

kglr
  • 394,356
  • 18
  • 477
  • 896
0

The OP includes a 9-element list:

list = {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}, {11, 12}, {13, 14, 15, 
   16}, {17, 18, 19, 20, 21, 22, 23}, {24}, {25, 26}, {27}, {4}}

For dividing the number 9 it into bins, consider:

QuotientRemainder[
    Length@list, #] /. {a_, b_} :> {Sequence @@ ConstantArray[#, a], 
     If[b != 0, b, Nothing]} & /@ Range[5]

{{1, 1, 1, 1, 1, 1, 1, 1, 1}, {2, 2, 2, 2, 1}, {3, 3, 3}, {4, 4, 1}, {5, 4}}

Define a function to Catenate n lists together using TakeList:

nCatenate[list_List, n_Integer] :=
 Catenate /@ 
  TakeList[list, 
   QuotientRemainder[Length@list, 
     n] /. {a_, b_} :> {Sequence @@ ConstantArray[n, a], 
      If[b != 0, b, Nothing]}]

nCatenate[list, 3]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, {13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}, {25, 26, 27, 4}}

nCatenate[list, 2]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {11, 12, 13, 14, 15, 16}, {17, 18,
19, 20, 21, 22, 23, 24}, {25, 26, 27}, {4}}

One can decide if the last (left over) items are to be kept.


Addendum

Another way of realizing sublist counts as shown above can be:

ips = IntegerPartitions[9]
Last /@ (MaximalBy[ips, Count[#]] & /@ Range[5])

{{1, 1, 1, 1, 1, 1, 1, 1, 1}, {2, 2, 2, 2, 1}, {3, 3, 3}, {4, 4,
1}, {5, 1, 1, 1, 1}}

Syed
  • 52,495
  • 4
  • 30
  • 85