2
inp = [1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17, 20, 25,27,28,29,31]

The expected output: If the adjacent variable is in series, fill with a hyphen. If not, append the given number.

Expected Output = [1-3,5,7-12,14,17,20,25,27-29,31]

I have taken an adjacent number using the below code. But the requirements are not satisfied.

inp = [1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17, 20, 25,27,28,29,31]
for x,y in zip(inp[::],inp[1::]):
    print(x,y)
James Z
  • 12,209
  • 10
  • 24
  • 44
abi varma
  • 31
  • 4

2 Answers2

4

You can use itertools.groupby:

from itertools import groupby

lst = [1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17, 20, 25,27,28,29,31]

out = []
for _, g in groupby(enumerate(lst), lambda k: k[1]-k[0]):
    g = [*g]
    if len(g) == 1:
        out.append(str(g[0][1]))
    else:
        out.append('{}-{}'.format(g[0][1], g[-1][1]))

print(out)

Prints:

['1-3', '5', '7-12', '14', '17', '20', '25', '27-29', '31']
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
2

This is a very simple task if you use the consecutive_groups function from more-itertools. This uses itertools.groupby under the hood, similar to @Andrej Kesely's answer. If you want to look at the source code to see how this is implemented, here is the function on GitHub.

from more_itertools import consecutive_groups

inp = [1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 14, 17, 20, 25, 27, 28, 29, 31]

result = [
    f"{group[0]}-{group[-1]}" if len(group) > 1 else f"{group[0]}"
    for group in map(list, consecutive_groups(inp))
]

print(result)

Output:

['1-3', '5', '7-12', '14', '17', '20', '25', '27-29', '31']
RoadRunner
  • 25,803
  • 6
  • 42
  • 75
  • 1
    Wow!!!. That was awesome. Thanks a lot. I will check the documentation to know more. Thanks for your reference. – abi varma May 17 '20 at 14:14