1

So I have string that represent numbers separate by '-' and and I need to write 2 generator the get this string and return the range of each numbers. For example the input string '1-2,4-4,8-10' need to return:

[1, 2, 4, 8, 9, 10]

So the first generator need to return list of numbers (could be list of string) for each iteration so this is what I have done:

def parse_ranges(ranges_string):
    range_splitter = (n for n in ranges_string.split(','))
    print(next(range_splitter).split('-'))
    print(next(range_splitter).split('-'))
    print(next(range_splitter).split('-')) 

This return:

['1', '2']
['4', '4']
['8', '10']

The second generator need to use this values and return each time all the numbers that exist in the range.

So currently this is what I have try:

numbers = [int(n) for n in list]

This returns list of numbers (minimum and maximum) and now I need to convert it to numbers inside this range.

martineau
  • 119,623
  • 25
  • 170
  • 301
falukky
  • 1,099
  • 2
  • 14
  • 34

5 Answers5

2

As you speak of generators, you would at least need to use yield.

Here are the two generators I think you need:

def singlerange(s):
    start, stop = map(int, s.split('-'))
    yield from range(start, stop + 1)

def multirange(s):
    for rng in s.split(','):
        yield from singlerange(rng)

Example run:

s = '1-2,4-4,8-10'
print(*multirange(s))   # 1 2 4 8 9 10
trincot
  • 317,000
  • 35
  • 244
  • 286
  • 1
    How this '*' convert the generator object ? – falukky Feb 26 '22 at 08:33
  • `*` is an operator that consumes the generator/iterator and [passes each individual value as a separate argument](https://stackoverflow.com/questions/2921847/what-does-the-star-and-doublestar-operator-mean-in-a-function-call) to `print`. You can do many things with iterators. If you want to get the list version of it, just do `list(multirange(s))`. – trincot Feb 26 '22 at 08:37
1

For each pair of start,end you need to get the corresponding range [start,end], in python range(start, end+1)

def parse_ranges(ranges_string):
    result = []
    for str_range in ranges_string.split(','):
        start, end = str_range.split("-")
        result.extend(range(int(start), int(end) + 1))
    return result

s = '1-2,4-4,8-10'
x = parse_ranges(s)
print(x)  # [1, 2, 4, 8, 9, 10]
azro
  • 53,056
  • 7
  • 34
  • 70
1

Since you need 2 generators. If you wanted to find all the numbers that exist between 2 numbers just use list(range(start, end+1)). This will include both the start and end number. This doesn't check for duplicate ranges or 2 ranges with intersecting numbers though. But it's a starting point

def stringRangetoNumberRange(stringRange):
    return [[int(j) for j in x.split('-')] for x in stringRange.split(',')]
    
def numberRangetoNumberList(numberRange):
    result = []
    
    for i in numberRange:
        result += list(range(i[0], i[1]+1))
    result.sort()
    return result
    
numberRange = stringRangetoNumberRange("1-2,4-4,8-10")
numberList = numberRangetoNumberList(numberRange)
print(numberList)

# [1, 2, 4, 8, 9, 10]
Kelvin
  • 79
  • 1
  • 7
0

You can try this.

def parse_ranges(ranges_string):
    l = ranges_string.split(',')
    range_list = []
    for a in l:
        range_list.append(a.split('-'))
    return range_list

def to_int(range_list):
    out_int = []
    for a in range_list:
        for a in range(int(a[0]),int(a[1])+1):
            out_int.append(a)
    return out_int
result = to_int(parse_ranges('1-2,4-4,8-10'))
print(result) # [1, 2, 4, 8, 9, 10]
codester_09
  • 5,622
  • 2
  • 5
  • 27
0

You can use one generator:

def parse_ranges(ranges: str):
for r in ranges.split(","):
    start, end = map(int, r.split("-"))
    yield from range(start, end+1)