2013-07-01 53 views
3

我有一個像結合連續編號爲範圍的元組

[38, 98, 110, 111, 112, 120, 121, 898] 

如何合併連續的編號爲代表的範圍內對名單?

所需的輸出:

['38', 
'98', 
'110,112', 
'120,121', 
'898'] 
+3

爲什麼是110 - > 112連續考慮? – hexparrot

+1

@hexparrot他有110,111,112;我認爲他意味着將所有數字都包含在「範圍」中,直到他達到不再連續的數字。 – 2rs2ts

+0

啊,這麼傻的監督。現在,我記得一個codegolf這樣做...... brb。 – hexparrot

回答

13

可以很好地與itertools.groupby通過注意到在清單中的項目,以及一個計數器之間的差別是恆定的,而數字是連續做

38 - 0 = 38 
98 - 1 = 97 
110 - 2 = 108 
111 - 3 = 108 
112 - 4 = 108 
120 - 5 = 115 
121 - 6 = 115 
898 - 7 = 891 

在這個例子中,108個組合在一起,115個組合在一起。現在一些代碼

>>> from itertools import groupby, count 
>>> L = [38, 98, 110, 111, 112, 120, 121, 898] 
>>> groups = groupby(L, key=lambda item, c=count():item-next(c)) 
>>> tmp = [list(g) for k, g in groups] 

看看我們至今

>>> tmp 
[[38], [98], [110, 111, 112], [120, 121], [898]] 

轉換爲所需的結果

>>> [str(x[0]) if len(x) == 1 else "{},{}".format(x[0],x[-1]) for x in tmp] 
['38', '98', '110,112', '120,121', '898'] 
4

一個直接的解決方案:

def ranger(lst): 
    fr, to = lst[0], lst[0] 
    for x in lst[1:]: 
     if x == to+1: 
      to = x 
     else: 
      yield fr, to 
      fr, to = x, x 
    yield fr, to 

res = [','.join(map(str, sorted(set(x)))) for x in ranger(lst)] 
+0

輸出不匹配它使單個數字的副本,並將它們配對 – Serial

+0

@ChristianCareaga修復。 – Elazar