1
$\begingroup$

The documentation for Partition shows an example of partitioning without padding, so that no elements are dropped, but the last sublist can be shorter.

Partition[Range[50], 8, 8, 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, 28, 29, 30, 31, 32}, {33, 34, 
   35, 36, 37, 38, 39, 40}, {41, 42, 43, 44, 45, 46, 47, 48}, {49, 50}} *)

The documentation for Partition in the Wolfram Language documentation (and presumably for the forthcoming version 10) has an additional example, where the partitioning starts from the end, and the first list is the shorter one. A similar example (but with actual padding not an empty list) is in the version 9 documentation under the Padding Alignment section of the documentation page.

However, partitioning from the end does not seem to result in all elements of the original list being preserved, regardless of whether padding is used or not. Notice that the last value (50) is missing from the result. (Output from version 9, but I have reason to believe that the behaviour from the current version of the Wolfram Language is similar.)

Partition[Range[50], 8, 8, -1, x]   
(* {{x, x, x, x, x, x, x, 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, 28, 29, 
  30, 31, 32, 33}, {34, 35, 36, 37, 38, 39, 40, 41}, {42, 43, 44, 45, 
  46, 47, 48, 49}} *)
Partition[Range[50], 8, 8, -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, 28, 29, 30, 31, 32, 33}, {34,
   35, 36, 37, 38, 39, 40, 41}, {42, 43, 44, 45, 46, 47, 48, 49}} *)

Is this a bug? Is there a way to ensure that partitioning from the end preserves all original elements of the list?

The context for this question is that I'm trying to create a little function that implements local shuffling, for inclusion in a little genealogical simulation I'm writing (on the theory that people in bygone eras were more likely to marry people form nearby than people from far away, but didn't systematically always marry the person next door).

localshuffle[list_List, window1_Integer?Positive, window2_Integer?Positive] /; 
  Length[list] > window2 && window2 > window1 :=
 Flatten[RandomSample /@ 
   Partition[ Flatten[RandomSample /@ Partition[list, window1, window1, 1, {}], 
     1], window2, window2, -1, {}], 1]

The number of elements should be the same as in the input but it is not. It does work if the -1 in the outer Partition is replaced with 1.

test = localshuffle[Range[50], 5, 8]
(* {3, 8, 6, 1, 4, 5, 2, 10, 7, 14, 13, 11, 12, 9, 18, 17, 15, 19, 22, \
16, 24, 20, 21, 23, 25, 32, 27, 29, 28, 33, 30, 31, 26, 41, 38, 39, \
36, 37, 40, 34, 35, 48, 50, 46, 49, 43, 45, 44, 42} *)

Length[test]
49
$\endgroup$

1 Answer 1

2
$\begingroup$
$Version

"9.0 for Mac OS X x86 (64-bit) (January 24, 2013)"

You need two items in the first list so the first element should appear at position -2 rather than -1.

Partition[Range[50], 8, 8, -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, 28, 29, 30, 31, 32, 33, 34}, {35, 36, 37, 38, 39, 40, 41, 42}, {43, 44, 45, 46, 47, 48, 49, 50}}

list = Range[RandomInteger[{40, 100}]];

len = Length[list]

75

n = RandomInteger[{5, 9}]

7

If[Mod[len, n] == 0, Partition[list, n], 
 Partition[list, n, n, -Mod[len, n], {}]]

{{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, 28, 29, 30, 31, 32, 33}, {34, 35, 36, 37, 38, 39, 40}, {41, 42, 43, 44, 45, 46, 47}, {48, 49, 50, 51, 52, 53, 54}, {55, 56, 57, 58, 59, 60, 61}, {62, 63, 64, 65, 66, 67, 68}, {69, 70, 71, 72, 73, 74, 75}}

$\endgroup$
5
  • $\begingroup$ Thanks Bob, but how do you then generalise this to functions where the length is not known upfront? Presumably something funky involving Mod? $\endgroup$
    – Verbeia
    Commented Jun 15, 2014 at 23:56
  • $\begingroup$ myPartition[d_, k_] := Partition[d, k, k, -Mod[Length@d, k], {}] $\endgroup$
    – wxffles
    Commented Jun 16, 2014 at 0:37
  • $\begingroup$ @Verbeia added above. $\endgroup$
    – Bob Hanlon
    Commented Jun 16, 2014 at 0:42
  • $\begingroup$ @wxffles try myPartition[Range[40], 5] $\endgroup$
    – Bob Hanlon
    Commented Jun 16, 2014 at 0:44
  • 1
    $\begingroup$ Thanks Bob - I think this is an "improvement opportunity" in the documentation - it is pretty confusing. $\endgroup$
    – Verbeia
    Commented Jun 16, 2014 at 2:26

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.