Python: check if an object is NOT an "array-type"

11,401

Solution 1

There is no term 'list-ish' and there is no magic build-in check_if_value_is_an_instance_of_some_i_dont_know_what_set_of_types.

You solution with not isinstance( value, (frozenset, list, set, tuple,) ) is pretty good - it is clear and explicit.

Solution 2

There is no such family – it's not well-defined, and naturally there's no way to check for it. The closest thing possible is an iterable that is not a string. You can test if the object for iterability and then explicitly check if it is a string:

if isinstance(ob, collections.Iterable) and not isinstance(ob, types.StringTypes):
    print "An iterable container"

A better approach would be to always ask for an iterable object, and when you need to pass a single string S, pass [S] instead. The ability to pass a string is a feature, e.g.:

alphabet = set('abcdefgijklmopqrstuvwxyz')

If you special-case string, you will:

  1. Break the ability to use your function with the most natural way to pass a collection of characters.
  2. Create inconsistency for user-defined string types and/or other containers that are string-ish (e.g. array.array can represent a chunk of data, just like string).

A string can be used to represent both a single piece of text and a collection of characters, and because of the second it is also list-ish.

Share:
11,401
amito
Author by

amito

Python and Web DeveloperLinkedIn

Updated on June 25, 2022

Comments

  • amito
    amito almost 2 years

    I'm looking for a way to test if an object is not of a "list-ish" type, that is - not only that the object is not iterable (e.g. - you can also run iter on a string, or on a simple object that implements iter) but that the object is not in the list family. I define the "list" family as list/tuple/set/frozenset, or anything that inherits from those, however - as there might be something that I'm missing, I would like to find a more general way than running isinstance against all of those types.

    I thought of two possible ways to do it, but both seem somewhat awkward as they very much test against every possible list type, and I'm looking for a more general solution.

    First option:

    return not isinstance( value, (frozenset, list, set, tuple,) )
    

    Second option:

    return not hasattr(value, '__iter__')
    

    Is testing for the __iter__ attribute enough? Is there a better way for finding whether an object is not a list-type?

    Thanks in advance.

    Edit:

    (Quoted from comment to @Rosh Oxymoron's Solution):
    Thinking about the definition better now, I believe it would be more right to say that I need to find everything that is not array-type in definition, but it can still be a string/other simple object...
    Checking against collections.Iterable will still give me True for objects which implement the __iter__ method.

  • amito
    amito over 12 years
    Thanks for the elaborate comment! However, thinking about the definition better now, I believe it would be more right to say that I need to find everything that is not array-type in definition (can be achieved by adding 'not' to the first condition in your if) but it can still be a string/other simple object... The best definition I can think of would be - anything that is not array-type in definition. Checking against collections.Iterable will still give me True for objects which implement the __iter__ method.