I want to write a function that accepts a parameter which can be either a sequence or a single value. The type of value is str, int, etc., but I don\'t want
Revised answer:
I don't know if your idea of "sequence" matches what the Python manuals call a "Sequence Type", but in case it does, you should look for the __Contains__ method. That is the method Python uses to implement the check "if something in object:"
if hasattr(X, '__contains__'):
print "X is a sequence"
My original answer:
I would check if the object that you received implements an iterator interface:
if hasattr(X, '__iter__'):
print "X is a sequence"
For me, that's the closest match to your definition of sequence since that would allow you to do something like:
for each in X:
print each
Sequences are described here: https://docs.python.org/2/library/stdtypes.html#sequence-types-str-unicode-list-tuple-bytearray-buffer-xrange
So sequences are not the same as iterable objects. I think sequence must implement
__getitem__
, whereas iterable objects must implement __iter__
.
So for example string are sequences and don't implement __iter__
, xrange objects are sequences and don't implement __getslice__
.
But from what you seen to want to do, I'm not sure you want sequences, but rather iterable objects.
So go for hasattr("__getitem__", X)
you want sequences, but go rather hasattr("__iter__", X)
if you don't want strings for example.
If strings are the problem, detect a sequence and filter out the special case of strings:
def is_iterable(x):
if type(x) == str:
return False
try:
iter(x)
return True
except TypeError:
return False
IMHO, the python way is to pass the list as *list. As in:
myfunc(item)
myfunc(*items)
The simplest method would be to check if you can turn it into an iterator. ie
try:
it = iter(X)
# Iterable
except TypeError:
# Not iterable
If you need to ensure that it's a restartable or random access sequence (ie not a generator etc), this approach won't be sufficient however.
As others have noted, strings are also iterable, so if you need so exclude them (particularly important if recursing through items, as list(iter('a')) gives ['a'] again, then you may need to specifically exclude them with:
if not isinstance(X, basestring)
You could pass your parameter in the built-in len() function and check whether this causes an error. As others said, the string type requires special handling.
According to the documentation the len function can accept a sequence (string, list, tuple) or a dictionary.
You could check that an object is a string with the following code:
x.__class__ == "".__class__