0

(Python) I have the following array

x=[1,2,3,4,5,6]

and I want this one

x=[[1,2],[2,3],[3,4],[4,5],[5,6]]

I used this function

def split(arr, size):
 arrs = []
 while len(arr) > size:
     pice = arr[:size]
     arrs.append(pice)
     arr   = arr[size:]
 arrs.append(arr)
 return arrs

But it only generates this

x=[[1,2],[3,4],[5,6]]
  • If looking for performance, use NumPy strides or `broadcasting` - https://stackoverflow.com/questions/40084931/taking-subarrays-from-numpy-array-with-given-stride-stepsize – Divakar Apr 16 '18 at 17:48
  • You have a simple error. Change `arr = arr[size:]` to `arr = arr[1:]` – pault Apr 16 '18 at 17:50
  • You say `x` is an array, but show a list. The code also generates lists. Is this a list problem or a numpy array one? I"m tempted to edit the tags, removing 'arrays', 'numpy' and 'split' – hpaulj Apr 16 '18 at 17:55
  • @pault is almost correct. use `arr = arr[size-1:]` I assume you're passing 2 for size. You haven't defined the correct result for other values so it might not be correct in those cases. – Jeff Learman Apr 16 '18 at 17:59
  • 1
    @JeffLearman I am pretty sure it should not be `size-1` although I agree that OP didn't specify. `arr = arr[1:]` returns a similar type output for all values of size (ie, lists of the same length, values consecutive). – pault Apr 16 '18 at 18:03
  • 1
    @pault: Perhaps you're right: it depends on what `size` is intended to mean. `size-1` works when size is 2, and does *something* that might be meaningful when size is >2. – Jeff Learman Apr 16 '18 at 18:08

6 Answers6

3

I suppose you want to develop your own code and not use libraries or built-in functions.

Your code is fine.

There's just one simple mistake: change the slice index from size to 1 in this line arr = arr[size:], where 1 means size - (size-1)

def split(arr, size):
    arrs = []
    while len(arr) > size:
        pice = arr[:size]
        arrs.append(pice)
        arr  = arr[1:]
    arrs.append(arr)
    return arrs

output:

[[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]

It also works for other sizes:

print split(x, 3)
print split(x, 4)

[[1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6]]
[[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
rafaelc
  • 57,686
  • 15
  • 58
  • 82
  • 1
    This doesn't work for `split(x, 3)`, etc. It *happens* to work in this one specific case, but it's wrong. – pault Apr 16 '18 at 17:48
  • 1
    you could simplify by noting that `size-(size-1) = 1` – pault Apr 16 '18 at 17:50
  • No I mean the correct thing to do is to not use `size` at all in the slice. The code should be `arr = arr[1:]`. You want to slide the list over by 1 each time. It is independent of `size`. – pault Apr 16 '18 at 17:53
  • @pault: Really? What's the semantics for `size`? The author doesn't say. – Jeff Learman Apr 16 '18 at 18:15
  • @JeffLearman this exchange happened before you posted your comment which correctly pointed out that OP didn't specify. I stand by my interpretation of the problem, though I recognize that you have a valid point. – pault Apr 16 '18 at 18:17
2

loop your array with index, then put [index : index+size] as one element of new array.

The codes will be like:

x=[1,2,3,4,5,6]
size = 2
print([x[index:index+size] for index in range(0, len(x)-size+1)])
size = 4
print([x[index:index+size] for index in range(0, len(x)-size+1)])

Output:

[[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]
[[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5, 6]]
[Finished in 0.189s]

or use zip() with size>1.

x=[1,2,3,4,5,6]
size = 2
print( [item for item in zip( *[x[index:len(x)+index-1] for index in range(0, size)])])
size = 4
print( [item for item in zip( *[x[index:len(x)+index-1] for index in range(0, size)])])

Output:

[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
[(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 6)]
[Finished in 0.284s]
Sphinx
  • 10,519
  • 2
  • 27
  • 45
1

Try this :

def split(arr, size):
    return [x[i:i+size] for i in range(0,len(x)-size+1)]
rafaelc
  • 57,686
  • 15
  • 58
  • 82
FadeoN
  • 101
  • 4
  • This could be right, depending on what's meant by `size`, which the OP doesn't specify. But it's very pythonic and shows the use of list comprehensions. And it's fixable if something else is meant by `size`. – Jeff Learman Apr 16 '18 at 18:17
1

You can use windowed() function from the more_itertools module.

from more_itertools import windowed
x = list(windowed(x, 2))

You can install it using pip

pip install more-itertools
Wasi
  • 1,473
  • 3
  • 16
  • 32
0
a = [1,2,3,4,5]

answer = list(map(list, zip(a, a[1:])))

print(answer)
rafaelc
  • 57,686
  • 15
  • 58
  • 82
tkhurana96
  • 919
  • 7
  • 25
0

You can use fancy indexing when using NumPy. This will require x to be converted to a numpy array. You will also need to create an array of incidences labeled ind below

x=[1,2,3,4,5,6]
x = np.array(x)

ind = np.arange(len(x)-1)[:,None] + np.arange(2)

x[ind]

array([[1, 2],
       [2, 3],
       [3, 4],
       [4, 5],
       [5, 6]])
DJK
  • 8,924
  • 4
  • 24
  • 40