0

I have a list of number. That list may be in series or without series. So we need output in following manner.

  1. if elements are in continuous series then we need to write start-last e.g. 8,9,10,11 then output would be 8-11.
  2. if any set of number is not in series then we need to write same value e.g. 1,3,4,5,7,8 then output would be 1,3-5,7,8. Here 1,3 (2 is missing in between) so it will display as 1,3 then follow rule 1.
  3. if only 2 elements are in series like 1,2 or 2,3 then no need to write 1-2 or 2-3. just same(1,2 or 2,3) is fine.

below is example of all rules.

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
Bimlesh Sharma
  • 186
  • 4
  • 18

1 Answers1

0

You could use 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)

yields

8-11
1-3,5,7-8,10-12,14
1,3-5,7-8
1,3-5,7-10

If your sequences are not strings, then simply remove the call to ast.literal_eval:

groups = cluster(list(test), maxgap=1)
Community
  • 1
  • 1
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677