def parse_ranges_v1(range_string): """This version causes a memory error for huge ranges...""" ranges = [tuple(map(int, r.split("-"))) for r in range_string.split(",")] result = [] for start, stop in ranges: result = [*result, *list(range(start, stop + 1))] for number in result: yield number def parse_ranges_v2(range_string): """This version seems more memory efficient.""" ranges = [tuple(map(int, r.split("-"))) for r in range_string.split(",")] for start, stop in ranges: for number in range(start, stop + 1): yield number def parse_ranges_v3(range_string): """This version handles single digits, Bonus2.""" ranges = [tuple(map(int, r.split("-"))) for r in range_string.split(",")] for limits in ranges: if len(limits) == 1: yield limits[0] else: start, stop = limits for number in range(start, stop + 1): yield number def parse_ranges_v4(range_string): """My take at Bonus3.""" # We prepare the data range_string = range_string.replace("->", "-") # We extract integer tuples from the data ranges = [] for subrange in range_string.split(","): splited = subrange.split("-") try: item = tuple(map(int, splited)) except ValueError: # This item shall then contains text in the 2nd part item = (int(splited[0]),) ranges.append(item) # We procede as before for limits in ranges: if len(limits) == 1: yield limits[0] else: start, stop = limits for number in range(start, stop + 1): yield number def parse_ranges_v5(range_string): """Revisiting the solution after reading Trey's answer. The part 'for (begin, _, end) in [subrange.partition("-")]' is tricky as it is here to 'iterate' over the one element list and thus assign the 3-tuple we need inside the comprehension. Comprehesion are a way to write for loops and the one we want to write is: ranges = [] for subrange in range_string.split(","): begin, _, end = subrange.partition("-") if end.isdecimal(): ranges.append(start, end) else: ranges.append(start, start) Read more here: https://nedbatchelder.com/blog/201802/a_python_gargoyle.html """ range_string = range_string.replace("->", "-") return ( number for start, stop in ( (begin, end) if end.isdecimal() else (begin, begin) for subrange in range_string.split(",") for (begin, _, end) in [subrange.partition("-")] ) for number in range(int(start), int(stop) + 1) ) # L'idée principale de la correction est l'expression de générateur : # (EXPRESSION for NOM in ITERABLE) qui permet de rester 'fainéant' de bout en bout ! # # Et bien sûr la gargouille for (begin, _, end) in [subrange.partition("-")] # à utiliser avec modération car la lisibilité compte ! parse_ranges = parse_ranges_v5