compact-number-list (3)
stepに対応するようにして、さらにイテレータ(無限リスト)に対応するように拡張してみた。
from itertools import izip def count2(start, step=1): cnt = start while True: yield cnt cnt += step def compact_number_list(seq): seq = iter(seq) curr, next_ = None, None while True: if not curr: try: curr = seq.next() except: break if not next_: try: next_ = seq.next() except: yield curr break c = count2(curr, next_-curr) c.next() c.next() has_step = False last = None for next2, cnt in izip(seq, c): if next2 == cnt: has_step = True last = next2 continue else: if has_step: if next_-curr == 1: yield [curr, last] else: yield [curr, last, next_-curr] curr, next_ = next2, None break else: yield curr curr = next_ next_ = next2 break else: if has_step: if next_-curr == 1: yield [curr, last] else: yield [curr, last, next_-curr] else: yield curr yield next_ break print list(compact_number_list([1, 3, 4, 5, 6, 12, 13, 15, 20, 25, 26, 27])) #=> [1, [3, 6], 12, 13, [15, 25, 5], 26, 27]
かなり汚すぎるので時間ができたら実装を書き直すつもり。あともう少しPythonの無限リストの扱いに関して研究するつもり。Pythonのイテレータ(およびジェネレータ)はHaskellの遅延リスト(lazy list)の部分集合的な機能しかないと思うので、何が足りないかをあとで考える。