我有一个像
这样的清单[38, 98, 110, 111, 112, 120, 121, 898]
如何将连续数字合并为代表范围的对?
期望的输出:
['38',
'98',
'110,112',
'120,121',
'898']
答案 0 :(得分: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']
答案 1 :(得分: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)]