6

Is there any equivalent to split for arrays?

a = [1, 3, 4, 6, 8, 5, 3, 4, 5, 8, 4, 3]

separator = [3, 4] (len(separator) can be any)

b = a.split(separator)

b = [[1], [6, 8, 5], [5, 8, 4, 3]]
7
  • No, there isn't; how would that make sense? You aren't even involving separator in your invented call. Commented Jan 11, 2016 at 22:10
  • does it have to be a list of lists, or do you just want to sort out the subarrays matching your separator? Commented Jan 11, 2016 at 22:10
  • 1
    Have you looked into itertools.groupby? Commented Jan 11, 2016 at 22:11
  • 2
    @TigerhawkT3 How would that help? Commented Jan 11, 2016 at 22:22
  • 2
    @TigerhawkT3 I don't see a good way to use it here... Commented Jan 11, 2016 at 22:31

4 Answers 4

4

No, but we could write a function to do such a thing, and then if you need it to be an instance method you could subclass or encapsulate list.

def separate(array,separator):
    results = []
    a = array[:]
    i = 0
    while i<=len(a)-len(separator):
        if a[i:i+len(separator)]==separator:
            results.append(a[:i])
            a = a[i+len(separator):]
            i = 0
        else: i+=1
   results.append(a)
   return results

If you wanted this to work as an instance method, we could do the following to encapsulate the list:

class SplitableList:
    def __init__(self,ar): self.ary = ar
    def split(self,sep): return separate(self.ary,sep)
    # delegate other method calls to self.ary here, for example
    def __len__(self): return len(self.ary)

a = SplitableList([1,3,4,6,8,5,3,4,5,8,4,3])
b = a.split([3,4]) # returns desired result

or we could subclass list like so:

class SplitableList(list):
    def split(self,sep): return separate(self,sep)

a = SplitableList([1,3,4,6,8,5,3,4,5,8,4,3])
b = a.split([3,4]) # returns desired result
Sign up to request clarification or add additional context in comments.

2 Comments

I think it doesn't work for [1, 3,4], it will return [[1]] instead of [[1], []]
You are right, and I wasn't sure if that empty list should occur or not (it should if the desire is to behave like the string split operator). I have edited the code to address that.
3

No there is not. You will have to write your own

or take this one:

def split(a, sep):
    pos = i = 0
    while i < len(a):
        if a[i:i+len(sep)] == sep:
            yield a[pos:i]
            pos = i = i+len(sep)
        else:
            i += 1
    yield a[pos:i]

print list(split(a, sep=[3, 4]))

Comments

0

You could join the list to a string using a non-numeric separator, then do the split:

>>> s = " {} ".format(" ".join(map(str, a)))  
>>> s
' 1 3 4 6 8 5 3 4 5 8 4 3 '
>>> [[int(y) for y in x.split()] for x in s.split(" 3 4 ")]
[[1], [6, 8, 5], [5, 8, 4, 3]]

The 2 extra spaces in the string take account of edge cases (e.g. a = [1, 3, 4]).

Comments

0

For efficiency (50 x) on big arrays, there is a np.split method which can be used. the difficulty is to delete the separator :

from pylab import *
a=randint(0,3,10)
separator=arange(2)
ind=arange(len(a)-len(separator)+1) # splitting indexes
for i in range(len(separator)): ind=ind[a[ind]==separator[i]]+1 #select good candidates
cut=dstack((ind-len(separator),ind)).flatten() # begin and end
res=np.split(a,cut)[::2] # delete separators
print(a,cut,res)

gives:

[0 1 2 0 1 1 2 0 1 1] [0 2 3 5 7 9] [[],[2],[1, 2],[1]]

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.