2016-01-11 16 views
5

Esiste un equivalente per dividere per gli array?Python usa split con le matrici

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]] 
+0

No, non lo è; come avrebbe senso? Non stai nemmeno coinvolgendo 'separator' nella tua chiamata inventata. – jonrsharpe

+0

deve essere una lista di liste, o vuoi solo ordinare i sottoarray corrispondenti al separatore? – jkalden

+1

Hai esaminato ['itertools.groupby'] (http://stackoverflow.com/questions/14529523/python-split-for-lists)? – TigerhawkT3

risposta

3

No, ma potremmo scrivere una funzione per fare una cosa del genere, e quindi se hai bisogno che sia un metodo di istanza potresti sottoclasse o incapsula l'elenco.

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 

Se si voleva far funzionare tutto questo come un metodo di istanza, potremmo effettuare le seguenti operazioni per incapsulare l'elenco:

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 

o potremmo sottoclasse lista in questo modo:

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 
+0

Penso che non funzioni per [1, 3,4], restituirà [[1]] invece di [[1], []] –

+0

Hai ragione, e non ero sicuro se quella lista vuota dovrebbe accadere o meno (dovrebbe essere se il desiderio è comportarsi come l'operatore split split). Ho modificato il codice per affrontarlo. – Matthew

+0

Sembra buono ora :) –

0

Si potrebbe unirsi alla lista di una stringa utilizzando un separatore non numerico, quindi effettuare la scissione:

>>> 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]] 

I 2 spazi aggiuntivi nella stringa tener conto dei casi limite (ad es a = [1, 3, 4]) .

3

No non c'è. Si dovrà scrivere il proprio

o prendere questo:

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])) 
0

Per l'efficienza (50 x) su grandi array, v'è un metodo np.split che può essere utilizzato. la difficoltà è quella di eliminare il separatore:

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) 

dà:

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