How do I distinguish a string from a sequence?

Tim Peters at
Fri Sep 28 21:39:50 CEST 2001

[Paul Moore]
> Yes, I know, a string is a sequence...
> I'm thinking of writing a function which can take either a
> string, or a sequence of strings, as an argument. A simplified example
> would be treating a single string as a 1-tuple - something like
>    def foo(args):
>       if # args is a string:
>          args = (args,)
>       for arg in args:
>          print arg
> But I'm not sure how best to distinguish a string from a sequence
> - after all, a string *is* a sequence.

I'd check for

    type(args) in types.StringTypes

under the theory that it gets the job done <wink>.  isinstance instead may
not be an appropriate test, as in 2.2 you can subclass str and unicode, and
how a subclass responds to iteration is up to the subclass -- it's not
necessarily the case that, e.g.,

    for x in object_of_unicode_subclass_type:

iterates over the characters.

It's tempting to try to check

    args and type(args[0]) is type(args)

under the theory that the first element of a str/unicode is again a
str/unicode.  In fact, that will probably work fine for your particular
application.  But in 2.2 "a sequence" (in the special sense of something
that can be iterated over) needn't support __getitem__, so that test may
blow up on the "args[0]" part.

Stick in tests to cover that too, and you'll soon appreciate why I settled

    type(args) in types.StringTypes

at the start <wink>.

More information about the Python-list mailing list