On Sep 2, 4:55 pm, bvdp <b...@mellowood.ca> wrote: > I'm trying to NOT create a parser to do this .... and I'm sure that > it's easy if I could only see the light! >
Well, this is a nice puzzler, better than a sudoku. Maybe a quick parser with pyparsing will give you some guidance on how to do this without a parser library: from pyparsing import * # relevant punctuation, suppress after parsing LBR,RBR,COLON = map(Suppress,"[]:") # expression to parse numerics and convert to int's integer = Regex("-?\d+").setParseAction(lambda t: int(t[0])) # first try, almost good enough, but wrongly parses "[2]" -> [2::] sliceExpr = ( LBR + Optional(integer,default=None) + Optional(COLON + Optional(integer,default=None), default=None) + Optional(COLON + Optional(integer,default=None), default=None) + RBR ) # better, this version special-cases "[n]" -> [n:n+1] # otherwise, just create slice from parsed int's singleInteger = integer + ~FollowedBy(COLON) singleInteger.setParseAction(lambda t : [t[0],t[0]+1]) sliceExpr = ( LBR + (singleInteger | Optional(integer,default=None) + Optional(COLON + Optional(integer,default=None), default=None) + Optional(COLON + Optional(integer,default=None), default=None) ) + RBR ) # attach parse action to convert parsed int's to a slice sliceExpr.setParseAction(lambda t: slice(*(t.asList()))) tests = """\ [2] [2:3] [2:] [2::2] [-1:-1:-1] [:-1] [::-1] [:]""".splitlines() testlist = range(10) for t in tests: parsedSlice = sliceExpr.parseString(t)[0] print t, parsedSlice, testlist[parsedSlice] Prints: [2] slice(2, 3, None) [2] [2:3] slice(2, 3, None) [2] [2:] slice(2, None, None) [2, 3, 4, 5, 6, 7, 8, 9] [2::2] slice(2, None, 2) [2, 4, 6, 8] [-1:-1:-1] slice(-1, -1, -1) [] [:-1] slice(None, -1, None) [0, 1, 2, 3, 4, 5, 6, 7, 8] [::-1] slice(None, None, -1) [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] [:] slice(None, None, None) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Yes, it is necessary to handle the special case of a "slice" that is really just a single index. If your list of parsed integers has only a single value n, then the slice constructor creates a slice (None,n,None). What you really want, if you want everything to create a slice, is to get slice(n,n+1,None). That is what the singleInteger special case does in the pyparsing parser. -- Paul -- http://mail.python.org/mailman/listinfo/python-list