2013-02-22 26 views
5

Aşağıdaki problemi yaşıyorum. Tam sayıların bir listesine sahip olmak, listenin bir listesinin içine, orijinal giriş listesinin iki öğesi arasındaki adım 1 olmadığında, bölmek istiyorum. Örneğin: input = [0, 1, 3, 5, 6, 7], çıktı = [[0, 1], [3], [5, 6, 7]]Python: aralarında adımlara göre tamsayıların bölünmüş listesi

Aşağıdaki işlevi yazdım, ama cehennem kadar çirkin, ve sizden biri var mı diye merak ediyordum daha güzel bir çözüm bulmama yardım et. Itertools'u kullanmaya çalıştım ama çözemedim.

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 

Çok teşekkürler:

İşte benim çözüm!

cevap

7

Bu döngü için kullanan herhangi 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

Güzel çözüm. Bence betimleme yararlı olacaktır: j = count() 'bir sayaç oluşturur. Sonraki (j) 'ye yapılan her çağrı int adımını 1'e döndürecektir. Belirgin bir python davranışı: fonksiyon argümanı için varsayılan değer fonksiyon oluşturulduğunda bir kez oluşturulur. Yani, j ', bir kere, bir kere,' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''' çağrısı çağrılarak başlatılır. "groupby", aynı anahtar değere sahip olan "inp" deki tüm öğeleri yinelenen "g" ye ekler. Anahtar değer değiştiyse - yeni g oluşturulur. Inp'den öğeler için: item = 0, anahtar = 0-0 = 0; madde = 1, anahtar = 1-1 = 0; öğe = 3, anahtar = 3-2 = 1; madde = 5, anahtar = 5-3 = 2 vb. – 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

Çok teşekkürler !!!!! – user1863555

0
İşte

olan bir solüsyon ile çalışır.

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

Bu yapardım nasıl:

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