2
$\begingroup$

What is the shortest way to take the first half of a list? Or to split a list into n equal parts? If the length is not 0 mod n, I would prefer to leave out the left over elements (that is more consistent with for example the behaviour of Partition, e.g. Partition[Array[a, 7], 3]). It feels like I am missing a basic elementary way to do this. Is there anything simpler than something like

#[[;; Floor[Length[#]/2]]] &

It feels like there should be something like Partition or [[;; ;;2]] that splits consecutively but I couldn't find it.

$\endgroup$
7
  • 2
    $\begingroup$ Partition - this is easy to find in the documentation - I don't know how you missed it - if you want the irregular elements using UpTo in Partition[{a, b, c, d, e}, UpTo[3]] gives {{a,b,c},{d,e}} $\endgroup$
    – flinty
    Jul 1, 2020 at 16:31
  • 2
    $\begingroup$ @flinty, that does not do what I want right? The 3 that you specify is the number upto which it includes not the number of partitions right? So the whole point would be that you have to figure out the correct partitions by taking Length[#]/n etc. So I don't see how that would help. You would basically resort to my example but more complicated. Am I misunderstanding something? $\endgroup$
    – Kvothe
    Jul 1, 2020 at 16:36
  • 1
    $\begingroup$ Hmm, yes I had not found that one. It could be marked as a duplicate, although some of the specifications required there for cases where Length[list] =!= 0 mod n are quite bad and against Mathematica conventions. I would prefer behavior consistent with for example Partition[Array[a, 7], 3], i.e. leaving out superflous elements. I will edit my question to make a clear difference (and leave it up to the Stackexchange gods to see whether it is different enough). $\endgroup$
    – Kvothe
    Jul 1, 2020 at 17:18
  • 4
    $\begingroup$ Take a look at NearEqualPartition. $\endgroup$ Jul 1, 2020 at 18:09
  • 1
    $\begingroup$ From the link supplied by @RohitNamjoshi, RatioPartition seems to be another possibility: ResourceFunction["RatioPartition"][Range[21], {50,50}] $\endgroup$
    – user1066
    Jul 1, 2020 at 18:30

2 Answers 2

5
$\begingroup$

Okay, I have to admit this is kind of cheating, but, since Mathematica hasn't had an ad hoc function for the frequently-used list equi-division... we can write a shorthand by ourselves?

ClearAll[Backslash];
Backslash[
  ls_?ListQ /; (D`len = Length[ls]; True),
  n_?IntegerQ /; 1 <= n <= D`len && (D`n = n; True),
  Optional[nth_?IntegerQ /; 1 <= nth <= D`n, All]
 ] := If[D`m = D`len~Quotient~n; nth === All,
    Partition[ls, D`m][[;; n]],
    ls[[(nth - 1) D`m + 1 ;; nth*D`m]]
]

Then you can ignore it and type like Esc \ Esc 4 to split a list into 4 equi-length sublists (leaving out the leftover elements):

Range[10]\4 (* \ = \[Backslash] *)
{{1, 2}, {3, 4}, {5, 6}, {7, 8}}

Take the first half of a list:

Range[10]\2\1
{1, 2, 3, 4, 5}

They don't need to be of strictly equal size? Not a problem. According to this, we can make modifications:

ClearAll[Backslash];
Backslash[
  ls_?ListQ /; (D`len = Length[ls]; True),
  n_?IntegerQ /; 1 <= n <= D`len && (D`n = n; True),
  Optional[nth_?IntegerQ /; 1 <= nth <= D`n, All]
 ] := If[nth === All,
  ls~TakeList~Table[Quotient[D`len + k, n], {k, 0, n - 1}],
  ls[[(D`s = Sum[Quotient[D`len + k, n], {k, 0, nth - 2}]) + 1
     ;; D`s + Quotient[D`len + nth - 1, n]]]
]

Example:

Range[10]\4
{{1, 2}, {3, 4}, {5, 6, 7}, {8, 9, 10}}
Range[10]\4\3
{5, 6, 7}

The query part is short, although... Alright, just take this as humor.

$\endgroup$
2
$\begingroup$

Like this?

list = Table[i, {i, 1, 10}];
n = Floor[Length[list]/2];
list2 = Drop[list, n]
list3 = Drop[list, -n]
$\endgroup$
1
  • 1
    $\begingroup$ I understand that you can do something simple like this. Indeed I included one such example in the question. And indeed I might resort to a hand constructed function doing something like this. (Although in that case I would like a more general form splitIntoParts[n_] that splits into n parts.) But really this action seems so elementary that I was hoping that either there was a built in function I missed or that someone could do it in a very small easily readable one liner. $\endgroup$
    – Kvothe
    Jul 1, 2020 at 16:41

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.