2013-02-22 4 views
5

Ich habe das folgende Problem. Wenn ich eine Liste von ganzen Zahlen habe, möchte ich sie in eine Liste von Listen aufteilen, wenn der Schritt zwischen zwei Elementen der ursprünglichen Eingabeliste nicht 1 ist. Zum Beispiel: input = [0, 1, 3, 5, 6, 7], Ausgabe = [[0, 1], [3], [5, 6, 7]]]Python: Split-Liste von ganzen Zahlen basierend auf Schritt zwischen ihnen

Ich schrieb die folgende Funktion, aber es ist häßlich und ich fragte mich, ob jemand von euch würde hilf mir, eine bessere Lösung zu finden. Ich habe versucht, Itertools zu benutzen, konnte es aber nicht lösen.

Hier ist meine Lösung:

def _get_parts(list_of_indices): 
    lv = list_of_indices 
    tuples = zip(lv[:-1], lv[1:]) 
    split_values = [] 
    for i in tuples: 
     if i[1] - i[0] != 1: 
      split_values.append(i[1]) 
    string = '/'.join([str(i) for i in lv]) 
    substrings = [] 
    for i in split_values: 
     part = string.split(str(i)) 
     substrings.append(part[0]) 
     string = string.lstrip(part[0]) 
    substrings.append(string) 
    result = [] 
    for i in substrings: 
     i = i.rstrip('/') 
     result.append([int(n) for n in i.split('/')]) 
    return result 

Vielen Dank! Diese

Antwort

7

funktioniert mit jedem iterable

>>> from itertools import groupby, count 
>>> inp = [0, 1, 3, 5, 6, 7] 
>>> [list(g) for k, g in groupby(inp, key=lambda i,j=count(): i-next(j))] 
[[0, 1], [3], [5, 6, 7]] 
+4

Schöne Lösung. Ich denke, die Beschreibung wird nützlich sein: 'j = count()' erstellt einen Zähler. Jeder Aufruf von 'next (j)' wird int Schritt um 1 zurückgeben. Nicht offensichtlich Python-Verhalten: Standardwert für Funktionsargument wird einmal bei der Funktionserstellung erstellt. Also wird "j" nur einmal mit count() initialisiert, beim nächsten Aufruf von 'key' wird arg' j' eine zuvor erstellte Instanz haben. 'groupby' fügt an iterable' g' alle Elemente von 'inp' an, die denselben Schlüsselwert haben. Wenn sich der Schlüsselwert geändert hat, wird ein neues g erstellt. Für Artikel von inp: item = 0, Schlüssel = 0-0 = 0; item = 1, Schlüssel = 1-1 = 0; item = 3, Schlüssel = 3-2 = 1; item = 5, key = 5-3 = 2 und so weiter. – stalk

2
def _get_parts(i, step=1): 
    o = [] 
    for x in i: 
     if o and o[-1] and x - step == o[-1][-1]: 
      o[-1].append(x) 
     else: 
      o.append([x]) 
    return o 

_get_parts([0, 1, 3, 5, 6, 7], step=1) 
# [[0, 1], [3], [5, 6, 7]]) 
+0

Vielen Dank !!!!! – user1863555

0

Hier ist eine Lösung für eine Schleife verwendet wird.

def splitbystep(alist): 
    newlist = [[alist[0]]] 
    for i in range(1,len(alist)): 
    if alist[i] - alist[i-1] == 1: 
     newlist[-1].append(alist[i]) 
    else: 
     newlist.append([alist[i]]) 
    return newlist 
0

Dies ist, wie ich es tun würde:

inp = [0, 1, 3, 5, 6, 7] 
base = [] 

for item in inp: 
    if not base or item - base[-1][-1] != 1: # If base is empty (first item) or diff isn't 1 
     base.append([item])     # Append a new list containing just one item 
    else: 
     base[-1].append(item)    # Otherwise, add current item to the last stored list in base 
print base         # => [[0, 1], [3], [5, 6, 7]]