bismigalis
у тебя оптимально получается, но 7.6MiB теряется на слайс, можно без слайса обойтись
#!/usr/bin/env python3
# приводит список целых к списку диапазонов
# [3, 1, 2, 5] -> ['1:3', '5']
# f: OM(Z) -> OM(seq S)
# F: OM(Z) -> (f, Z, Q, Z)
#
# F: om -> (f(om), p, q, n)
#
# F(dt) = (dt, неопр, нет, 0)
# G = | (f(om), x, нет, 0), если p = неопр
# | (f(om) * p, x, нет, 0), если p + 1 != x и не q
# | (f(om) * (n, p), x, нет, 0), если (p + 1 != x или last(x)) и q
# | (f(om), x, да, p), если p + 1 = x и не q
# | (f(om), x, да, n), если p + 1 = x
class NotAListError(TypeError):
pass
def convert_any_order(lst):
"""Convert integers in any order to single and range strings."""
if type(lst) != list:
raise NotAListError('the argument should be a list')
fmt = '{}:{}'
lst.sort()
out = []
prev, inrange, first = None, False, 0
for x in lst:
if prev is None:
pass
elif prev + 1 != x:
if inrange:
inrange = False
out.append(fmt.format(first, prev))
else:
out.append(str(prev))
elif not inrange:
inrange, first = True, prev
prev = x
if inrange:
out.append(fmt.format(first, prev))
elif prev is not None:
out.append(str(prev))
return out
это без среза, но оно медленнее немного
[guest@localhost timecmp]$ ./timecmp.py
[0.6980301569997209, 0.6972508899998502, 0.6992985159999989]
[0.7046079839997219, 0.7039838179998696, 0.6905217889998312]
[0.7073219859998972, 0.7085624579999603, 0.706647607999912]
[guest@localhost timecmp]$
1) со срезом
2) со срезом через itertools
3) без среза