Вот вариант:
def custom_split(s):
def int_range_expand(s):
try:
return [int(s)]
except ValueError:
try:
start, end = map(int, s.split('-'))
return range(start, end+1)
except Exception:
pass
return [s]
return sum(map(int_range_expand, s.split('.')), [])
>>> custom_split('Oreo.12.37-40.Apple.78')
['Oreo', 12, 37, 38, 39, 40, 'Apple', 78]
Используется подход EAFP , шаги которого разбиты ниже:
1. custom_split('Oreo.12.37-40.Apple.78')
2. s <= 'Oreo.12.37-40.Apple.78'
3. s.split('.') => ['Oreo', '12', '37-40', 'Apple', '78']
4. map(int_range_expand, ['Oreo', '12', '37-40', 'Apple', '78'])
=> [['Oreo'], [12], [37, 38, 39, 40], ['Apple'], [78]]
5. sum([['Oreo'], [12], [37, 38, 39, 40], ['Apple'], [78]], [])
=> ['Oreo', 12, 37, 38, 39, 40, 'Apple', 78]
Функция int_range_expand()
из шага 4 всегда возвращает список. Если аргумент является строкой или int, результат будет иметь только один элемент, но если это диапазон типа 37-40
, то он будет содержать каждое целое число в этом диапазоне. Это позволяет нам легко объединить все полученные списки в один список.
Шаг 5 аналогичен itertools.chain
, который более эффективен, но требует импорта модуля, в зависимости от вас.