Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
share|improve this question
add comment

1 Answer 1

up vote 2 down vote accepted
$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}}

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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