Search code examples
pythonnumeric-ranges

Interpreting Number Ranges in Python


In a Pylons webapp, I need to take a string such as "<3, 45, 46, 48-51, 77" and create a list of ints (which are actually IDs of objects) to search on.

Any suggestions on ways to do this? I'm new to Python, and I haven't found anything out there that helps with this kind of thing.

The list would be: [1, 2, 3, 45, 46, 48, 49, 50, 51, 77]


Solution

  • Use parseIntSet from here

    I also like the pyparsing implementation in the comments at the end.

    The parseIntSet has been modified here to handle "<3"-type entries and to only spit out the invalid strings if there are any.

    #! /usr/local/bin/python
    import sys
    import os
    
    # return a set of selected values when a string in the form:
    # 1-4,6
    # would return:
    # 1,2,3,4,6
    # as expected...
    
    def parseIntSet(nputstr=""):
        selection = set()
        invalid = set()
        # tokens are comma seperated values
        tokens = [x.strip() for x in nputstr.split(',')]
        for i in tokens:
            if len(i) > 0:
                if i[:1] == "<":
                    i = "1-%s"%(i[1:])
            try:
                # typically tokens are plain old integers
                selection.add(int(i))
            except:
                # if not, then it might be a range
                try:
                    token = [int(k.strip()) for k in i.split('-')]
                    if len(token) > 1:
                        token.sort()
                        # we have items seperated by a dash
                        # try to build a valid range
                        first = token[0]
                        last = token[len(token)-1]
                        for x in range(first, last+1):
                            selection.add(x)
                except:
                    # not an int and not a range...
                    invalid.add(i)
        # Report invalid tokens before returning valid selection
        if len(invalid) > 0:
            print "Invalid set: " + str(invalid)
        return selection
    # end parseIntSet
    
    print 'Generate a list of selected items!'
    nputstr = raw_input('Enter a list of items: ')
    
    selection = parseIntSet(nputstr)
    print 'Your selection is: '
    print str(selection)
    

    And here's the output from the sample run:

    $ python qq.py
    Generate a list of selected items!
    Enter a list of items: <3, 45, 46, 48-51, 77
    Your selection is:
    set([1, 2, 3, 45, 46, 77, 48, 49, 50, 51])