6
$\begingroup$

I have a list as

{1,2,3,4,5,6,7,8,9}

I want to extract a new list as

{{1,2},{2,3},{3,4},{4,5},{5,6},{6,7},{7,8},{8,9},{9,1}}

I've tried to search Partition, but it didn't give me what I want. Or I've missed out something. Can you please suggest me a way to do that?

$\endgroup$
6
  • 5
    $\begingroup$ Partition[{1, 2, 3, 4, 5, 6, 7, 8, 9}, 2, 1, 1]; look up the fourth argument of Partition[] in the docs. $\endgroup$ – J. M.'s torpor Jan 6 '19 at 7:56
  • $\begingroup$ @N.T.C. It is not seldom that a question of the form"How do I xyz?" is answered by "Use the comman Xyz. So in principle, it should be easy to find the command in the documentation. For example, this would have been a good starting point for a search, in particular the section "Rearranging & Restructuring Lists". $\endgroup$ – Henrik Schumacher Jan 6 '19 at 8:44
  • $\begingroup$ I did, but didn't understand it. Could you please elaborate a bit more about each parameter? $\endgroup$ – N.T.C Jan 6 '19 at 8:44
  • $\begingroup$ I will try that next time thanks @HenrikSchumacher $\endgroup$ – N.T.C Jan 6 '19 at 8:47
  • $\begingroup$ N.T.C, if you want to contact another user within a comment that does not directly follow another comment by that user, you can ping them with, e.g. @J.M. $\endgroup$ – Henrik Schumacher Jan 6 '19 at 8:55
8
$\begingroup$
a = {1, 2, 3, 4, 5, 6, 7, 8, 9};

The command

Partition[a, 2]

just partitions the input into as many nonoverlapping pairs as possible:

{{1, 2}, {3, 4}, {5, 6}, {7, 8}}

The three-argument version creates pairs with an offset of `1:

Partition[a, 2, 1]

{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}}

That is already very close to what you want!

In order to pair also the last element with the first, use the four argument version of Partition to make it cycle

Partition[a, 2, 1, {1, 1}]

{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 1}}

whose shorter version is

Partition[a, 2, 1, 1]

In the usage notes of Partition (?Partition), this is somewhat hidden. The notes state (highlighting by me):

Partition[list,n,d,{Subscript[k, L],Subscript[k, R]}] specifies that the first element of list should appear at position Subscript[k, L] in the first sublist, and the last element of list should appear at or after position Subscript[k, R] in the last sublist. If additional elements are needed, Partition fills them in by treating list as cyclic.

$\endgroup$
6
$\begingroup$

For the specific case you can also use

lst = Range[9];
Transpose[{lst, RotateLeft[lst]}]

{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 1}}

which is the same result Partition[lst, 2, 1, 1] gives.

$\endgroup$
5
$\begingroup$

I propose you another option that works similarly to Partition[list,n,d,{Subscript[k, L],Subscript[k, R]}] but making use of other list-manipulation functions that might be useful in other contexts.

a = {1, 2, 3, 4, 5, 6, 7, 8, 9};
Partition[Riffle[a, RotateLeft[a, 1]], 2]
$\endgroup$
5
$\begingroup$

Explanation of overhangs

This answer is in response to the comment

I did, but didn't understand it. Could you please elaborate a bit more about each parameter?

As J.M. and Henrik have noted, this problem can be solved with the fourth argument of Partition, the so-called overhangs. I will explain in detail how overhangs work.

l = Range[3]

{1, 2, 3}

Partition[l, 2, 1, {-1, -1}]

{{3, 1}, {1, 2}, {2, 3}}

To understand why the result above is what it is, imagine that you have a window of size two that you slide across the list. Just as if you were computing a moving average over the current element and the one before it. The overhangs specify where this window starts.

{3, 1} is the first sublist of the result. The first overhang in {-1, -1} refers to this sublist. It says that the first element in the original list should be the last element (-1) of the first sublist.

{2, 3} is the last sublist of the result. The second overhang in {-1, -1} refers to this sublist. It says that the first element in the original list should be the last element (-1) of the last sublist.

The first overhang specifies something about the first sublist in the result, and the second overhang specifies something about the last sublist in the result.

Let's now specify that the first sublist should not wrap around to the end, while the last sublist should. This is the opposite of what we did before. Since the first sublist should not wrap around, we want the first element of the first sublist to be the first element of the original list, i.e. 1. Since the last element of the last sublist should be the first element of the original list, we want it to be 1.

Partition[l, 2, 1, {1, 1}]

{{1, 2}, {2, 3}, {3, 1}}

Using this type of reasoning, you should be able to understand there as well:

Partition[l, 2, 1, {-1, 1}]

{{3, 1}, {1, 2}, {2, 3}, {3, 1}}

Partition[l, 2, 1, {1, -1}]

{{1, 2}, {2, 3}}

This reasoning also works for larger windows. Here's an example with a window size of 3, where we specify that the third element of the first sublist should be the first element of the original list.

Partition[Range[5], 3, 1, {3, -1}]

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

Returning to the idea of the sliding window, we can also think of the overhang as specifying that, in this last example, the sliding window should start two steps to the left of the first element. But what is to the left of the first element? As we have seen, the list is padded cyclically by default. To the left of the first element will then be the last elements of the list.

Other paddings can be set with the fifth argument of Partition:

Partition[Range[5], 3, 1, {3, -1}, 0]

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

With this setting, the elements to the left of the first element are all zero, and the same goes for the elements to the right of the last element:

Partition[l, 2, 1, {-1, 1}, 0]

{{0, 1}, {1, 2}, {2, 3}, {3, 0}}

$\endgroup$
1
  • 1
    $\begingroup$ Thank you so much for this wonderful and enlightening explanation. Very helpful!! $\endgroup$ – Jack LaVigne Jan 6 '19 at 15:32
0
$\begingroup$

For the sake of completeness (although this answer in no way whatsoever exhausts the topic) one should include ListCorrelate/ListConvolve.

Below is a number of arguments used in ListCorrelate/ListConvolve in order to achieve the desired result; since it's a lengthy list there will be a short comment on their individual purpose although they are exhaustively discussed in the documentation.

ker = {1, 1}; (* the kernel or what 'slides' over the list*)
list = Range[9]; (* input list *)
klist = {1, 1}; (* controls overhangs *)
padding = First[list]; (* use first element in input 'list' for padding purposes *)
g = Times; (* default value *)
h = List; (* default value is Plus *)

Since the required output consists of (successive) pairs of elements from the input list, ker should be a two-element list, otherwise it would be probably more of a hassle if not outright impossible to get the desired output. klist depends on which function is used (see below). padding should be self explanatory. g and h are the functions used by default when combining the kernel of the convolution/correlation with the appropriately selected elements of the input list.

The desired output can be obtained by evaluating

ListConvolve[ker, inpt, -klist, padding, g, h]

or

ListCorrelate[ker, inpt, klist, padding, g, h]

In both cases one obtains

{{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 6}, {6, 7}, {7, 8}, {8, 9}, {9, 1}}

Notice how klist enters with a - in ListConvolve.

$\endgroup$

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