我有一个号码列表。该列表可以是串联的也可以是没有系列的。所以我们需要以下列方式输出。
是所有规则的示例。
8,9,10,11 = 8-11
1,2,3,5,7,8,10,11,12,14 = 1-3,5,7,8,10-12,14
1,3,4,5,7,8 = 1,3-5,7,8
1,3,4,5,7,8,9,10 = 1,3-5,7-10
答案 0 :(得分:0)
您可以使用Raymond Hettinger's cluster function:
import ast
def cluster(data, maxgap, key=None):
"""Arrange data into groups where successive elements
differ by no more than *maxgap*
>>> cluster([1, 6, 9, 100, 102, 105, 109, 134, 139], maxgap=10)
[[1, 6, 9], [100, 102, 105, 109], [134, 139]]
>>> cluster([1, 6, 9, 99, 100, 102, 105, 134, 139, 141], maxgap=10)
[[1, 6, 9], [99, 100, 102, 105], [134, 139, 141]]
https://stackoverflow.com/a/14783998/190597 (Raymond Hettinger)
"""
data.sort()
groups = [[data[0]]]
for item in data[1:]:
if key:
val = key(item, groups[-1])
else:
val = abs(item - groups[-1][-1])
if val <= maxgap:
groups[-1].append(item)
else:
groups.append([item])
return groups
tests = ['8,9,10,11', '1,2,3,5,7,8,10,11,12,14', '1,3,4,5,7,8', '1,3,4,5,7,8,9,10']
for test in tests:
groups = cluster(list(ast.literal_eval(test)), maxgap=1)
result = ','.join(['{}-{}'.format(grp[0],grp[-1]) if len(grp)>1 else str(grp[0])
for grp in groups])
print(result)
产量
8-11
1-3,5,7-8,10-12,14
1,3-5,7-8
1,3-5,7-10
如果您的序列不是字符串,则只需删除对ast.literal_eval
的调用:
groups = cluster(list(test), maxgap=1)