3

我有一个类似的清单

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

如何将连续数字合并成一对表示范围的数字?

所需的输出:

['38',
 '98', 
 '110,112',
 '120,121',
 '898']
4

2 回答 2

15

您可以使用 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']
于 2013-07-01T23:17:16.997 回答
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)]
于 2013-07-01T23:19:45.227 回答