how to find the type of a list element?

Alex Martelli aleaxit at yahoo.com
Sun Nov 19 03:34:03 EST 2000


<lobozc at my-deja.com> wrote in message news:8v7qsd$poo$1 at nnrp1.deja.com...
> a list like [1,2,3,[4,5],6,7] is passed to a procedure
> how can a procedure find whether a list element is a 'scalar' or a list?

It depends: what does your procedure want to do regarding
elements that, why not being specifically _lists_, are nevertheless
_sequences_?  These include:
    strings
    tuples
    arrays (the Python kind)
    arrays (the Numeric kind)
    UserLists
    ...

If you're happy with treating each of these as 'scalar', then it's
easy:
    def scalar(element):
        return type(element) != type([])

For most applications, this can be considered a litte restrictive,
though.

The most generally useful pragmatical definition of 'sequence',
in my experience, turns out to be 'anything that can be iterated
on (with the for-statement protocol), except a string, which is
best treated as a scalar although it _can_ be iterated on'.

'Something that can be iterated on' is best verified by trying
to iterate, and catching the Type-Error in case it can't be.  I.e.:

    def scalar(element):
        t=type(element)
        if t in (type(''), type(u'')): return 1
        try:
            for x in element:
                return 0 # non-empty sequence
            else:
                return 0 # empty sequence
        except TypeError:
            return 1    # non-sequence


> I know I could, say, try to use exceptions for that - but I hope there
> is a better way.

To test if some operation can be performed, it's hard indeed in
the general case to do better than "just try, catching suitable
exceptions to inform you that 'no, it could not'".  The only
substantial 'improvement' may be to wrap the try/catch and
related plumbing up in a testing-function, then use that --
it's most often going to be better than coding the tests inline.

And it turns out that 'is the situation such that this operation
can be performed?' IS what we want BY FAR most of the time
when our spontaneous expression (if we come from statically
typed languages, particularly) is 'is this object of such and
such type?'.  Testing for type is possible, but it's not normally
'a good thing'... it's unduly restrictive more often than not.

Of course, if you fully control the 'client-code' (that will
build data structures to pass to the code which, among
other things, does such tests), you can get away with a
cheaper type-test in the original cut of the testing-code,
based on the 'do the simplest thing that could possibly
work'.  Just be aware that you WILL have to refactor the
testing-code at some point, unless your whole program
is a one-off experiment (and that many programs born
as such one-offs turn out to survive and evolve...:-).  If
you test in a single 'scalar' function, it will be easy and
painless to 'refactor' for more accuracy in the test -- just
update that single function...


Alex






More information about the Python-list mailing list