Python: check if an object is NOT an "array-type"
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:
- Break the ability to use your function with the most natural way to pass a collection of characters.
- 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.
Comments
-
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 againstcollections.Iterable
will still give me True for objects which implement the__iter__
method. -
amito over 12 yearsThanks 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.