Haskell風range表記
Haskellのリスト表記便利だわーと思ったのでpythonでそれっぽく。使用に堪えるかどうかはしらん。
#!/usr/bin/env python # -*- coding: utf-8 -*- import operator import re # # Haskell-like range notation # def hrange(pattern): _numeric_pattern = r'-?\d+(\.\d+)?' _range_pattern = re.compile(r'\[(?P<first>{0})\s*(,\s*(?P<second>{0}))?\s*\.\.\s*(?P<end>{0})?\]'.format(_numeric_pattern)) # generator factory def countgen(first, second, end): def gen(): now = first step = second - first ope = operator.le if step>0 else operator.ge while (end is None) or ((end is not None) and ope(now, end)): yield now now += step return gen() # string to (int|float) def toVal(numstr): try: if numstr is None: return None elif re.match(r'^-?\d+$', numstr): return int(numstr) else: return float(numstr) except ValueError: return None m = _range_pattern.match(pattern) if m: first, second, end = [toVal(m.group(x)) for x in ('first', 'second', 'end')] if not second: second = first+1 return countgen(first, second, end) else: raise ValueError() '''\ usage: [first_value(,second_value)..(end_value)] hrange('[1,2..10]') => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] hrange('[1,3..10]') => [1, 3, 5, 7, 9] hrange('[1,2.5..10]') => [1, 2.5, 4.0, 5.5, 7.0, 8.5, 10.0] hrange('[4,3..0]') => [4, 3, 2, 1, 0] hrange('[0,5..]') => [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, ... hrange('[1,1..]') => [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... hrange('[10..]') => [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, ... '''