3
$\begingroup$

If I had a list of let's say 20 elements, how could I split it into two separate lists that contain every other 5 elements of the initial list?

For example:

list={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
function[list]
(*
{1,2,3,4,5,11,12,13,14,15}
{6,7,8,9,10,16,17,18,19,20}
*)

Follow-up question:

Thanks to the numerous answers! Is there a way to revert this process? Say we start from two lists and I would like to end up with the listabove:

list1={1,2,3,4,5,11,12,13,14,15}
list2={6,7,8,9,10,16,17,18,19,20}
function[list1,list2]
(*
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
*)
$\endgroup$

4 Answers 4

4
$\begingroup$
ClearAll[f1, f2]
f1[lst_, k_] := Join @@ Partition[lst[[# ;;]], k, 2 k, 1, {}] & /@ {1, k + 1}

{list1, list2} = f1[list, 5]

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

An alternative way using the (still undocumented) 6th argument of Partition:

ClearAll[f1, f2]
f2[lst_, k_] := Partition[Drop[lst, #], k, 2 k, 1, {}, Sequence] & /@ {0, k}

{list1, list2} = f2[list, 5]

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

Update: To revert the process:

ClearAll[fb]
fb[lst1_, lst2_, k_] := Join @@ Riffle @@ (Partition[#, k, k, 1, {}] & /@ {lst1, lst2})

fb[list1, list2, 5]

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

$\endgroup$
4
  • $\begingroup$ Is there a way to revert this process? Please see the updated question. $\endgroup$
    – xabdax
    Aug 23, 2019 at 16:52
  • $\begingroup$ @xabdax, please see the update. $\endgroup$
    – kglr
    Aug 23, 2019 at 17:48
  • $\begingroup$ Thanks. It does not seem to be working for longer lists, length 40 for instance. $\endgroup$
    – xabdax
    Aug 23, 2019 at 18:08
  • $\begingroup$ @xabdax, please see the new version of the update. $\endgroup$
    – kglr
    Aug 23, 2019 at 18:19
4
$\begingroup$
Flatten /@ {#[[1 ;; ;; 2]], #[[2 ;; ;; 2]]} &@Partition[list, 5]

gives desired

{{1, 2, 3, 4, 5, 11, 12, 13, 14, 15}, {6, 7, 8, 9, 10, 16, 17, 18, 19, 20}}
$\endgroup$
0
1
$\begingroup$

You could use:

function = Flatten[Transpose[Fold[Partition, #, {5, 2}]], {{1}, {2, 3}}] &;

If the length of the input is not a multiple of 10, it will effectively cut off the remainder at the end.

$\endgroup$
1
$\begingroup$

Using UpTo: (with a list containing 23 elements)

list = Range[23];

Clear[chunk, unchunk];
chunk[k_List, n_ /; n ∈ PositiveIntegers] := 
 Flatten /@ {#[[1 ;; ;; 2]], #[[2 ;; ;; 2]]} &@Partition[k, UpTo[n]]

unchunk[{a_List, b_List}, n_ /; n ∈ PositiveIntegers] :=
 Catenate@Riffle[Partition[a, UpTo[n]], Partition[b, UpTo[n]]]

Usage:

Echo@unchunk[Echo@chunk[list, 5], 5];

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.