Reputation: 445
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.
Upvotes: 8
Views: 13514
Reputation: 29727
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.
Upvotes: 8
Reputation: 21055
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:
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.
Upvotes: 3