Search code examples
pythontypessequences

Correct way to detect sequence parameter?


I want to write a function that accepts a parameter which can be either a sequence or a single value. The type of value is str, int, etc., but I don't want it to be restricted to a hardcoded list. In other words, I want to know if the parameter X is a sequence or something I have to convert to a sequence to avoid special-casing later. I could do

type(X) in (list, tuple)

but there may be other sequence types I'm not aware of, and no common base class.

-N.

Edit: See my "answer" below for why most of these answers don't help me. Maybe you have something better to suggest.


Solution

  • The problem with all of the above mentioned ways is that str is considered a sequence (it's iterable, has getitem, etc.) yet it's usually treated as a single item.

    For example, a function may accept an argument that can either be a filename or a list of filenames. What's the most Pythonic way for the function to detect the first from the latter?

    Based on the revised question, it sounds like what you want is something more like:

    def to_sequence(arg):
        ''' 
        determine whether an arg should be treated as a "unit" or a "sequence"
        if it's a unit, return a 1-tuple with the arg
        '''
        def _multiple(x):  
            return hasattr(x,"__iter__")
        if _multiple(arg):  
            return arg
        else:
            return (arg,)
    
    >>> to_sequence("a string")
    ('a string',)
    >>> to_sequence( (1,2,3) )
    (1, 2, 3)
    >>> to_sequence( xrange(5) )
    xrange(5)
    

    This isn't guaranteed to handle all types, but it handles the cases you mention quite well, and should do the right thing for most of the built-in types.

    When using it, make sure whatever receives the output of this can handle iterables.