views:

3566

answers:

7

I am looking for a way to easily split a python array in half.

So that if I have an array:

A = [0,1,2,3,4,5]

I would be able to get:

B = [0,1,2]

C = [3,4,5]
+5  A: 
def splitter(A):
    B = A[0:len(A)//2]
    C = A[len(A)//2:]

 return (B,C)

I tested, and the double slash is required to force int division in python 3. My original post was correct, although wysiwyg broke in Opera, for some reason.

Stefan Kendall
+10  A: 
A = [1,2,3,4,5,6]
B = A[:len(A)/2]
C = A[len(A)/2:]

If you want a function:

def split_list(a_list):
    half = len(a_list)/2
    return a_list[:half], a_list[half:]

A = [1,2,3,4,5,6]
B, C = split_list(A)
jcoon
You need to force int division in Python 3.// is required.
Stefan Kendall
+3  A: 

B,C=A[:len(A)/2],A[len(A)/2:]

John Montgomery
I think you forgot the divide by 2 step. :)
Stefan Kendall
Yep, I did. Edited it two seconds after posting...
John Montgomery
+2  A: 

Using list slicing. The syntax is basically my_list[start_index:end_index]

>>> i = [0,1,2,3,4,5]
>>> i[:3] # same as i[0:3] - grabs from first to third index (0->2)
[0, 1, 2]
>>> i[3:] # same as i[3:len(i)] - grabs from fourth index to end
[3, 4, 5]

To get the first half of the list, you slice from the first index to len(i)/2...

>>> i[:len(i)/2]
[0, 1, 2]

..and the swap the values around to get the second half:

>>> i[len(i)/2:]
[3, 4, 5]
dbr
+5  A: 

A little more generic solution (you can specify the number of parts you want, not just split 'in half'):

EDIT: updated post to handle odd list lengths

EDIT2: update post again based on Brians informative comments

def split_list(alist, wanted_parts=1):
    length = len(alist)
    return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] 
             for i in range(wanted_parts) ]

A = [0,1,2,3,4,5,6,7,8,9]

print split_list(A, wanted_parts=1)
print split_list(A, wanted_parts=2)
print split_list(A, wanted_parts=8)
ChristopheD
When the list doesn't divide evenly (eg split_list([1,2,3], 2) ) this will actually return wanted_parts+1 lists.
Brian
That's correct, i was in doubt as what should be the right approach (have one more part or have the last list have one more item).I'll update my post, thanks for commenting.
ChristopheD
Actually, this still won't work: you may have a remainder > 1. split_list(range(5),3) will give 5 lists with the above code. Dealing with those cases is also trickier, as you need to spread the list out evenly (eg. for a 19 element list in 10 parts, you don't want 9*1 item and one with 9.)
Brian
A better way I think would be: length = len(alist); return [ alist[i*length // wanted_parts: (i+1)*length // wanted_parts] for i in range(wanted_parts) ]. That way you get an even as possible distribution, and always get exactly wanted_parts items (even pads with [] if wanted_parts > len(A))
Brian
Very nice solution, thanks a lot. A lot shorter also then the way i was thinking in... i'll update my post.
ChristopheD
+2  A: 

While the answers above are more or less correct, you may run into trouble if the size of your array isn't divisible by 2, as the result of a / 2, a being odd, is a float in python 3.0, and in earlier version if you specify from __future__ import division at the beginning of your script. You are in any case better off going for integer division, i.e. a // 2, in order to get "forward" compatibility of your code.

+1  A: 

f = lambda A, n=3: [A[i:i+n] for i in range(0, len(A), n)]

f(A)

n - the predefined length of result arrays

Jaro