这是一个带有一些文档测试的通用解决方案来演示:
def is_sequence(arg):
"""
SYNOPSIS
Test if input is iterable but not a string.
DESCRIPTION
Type checker. True for any object that behaves like a list, tuple or dict
in terms of ability to iterate over its elements; but excludes strings.
See http://stackoverflow.com/questions/1835018
PARAMETERS
arg Object to test.
RETURNS
True or False
EXAMPLES
## string
>>> is_sequence('string')
False
## list
>>> is_sequence([1, 2, 3,])
True
## set
>>> is_sequence(set([1, 2, 3,]))
True
## tuple
>>> is_sequence((1, 2, 3,))
True
## dict
>>> is_sequence(dict(a=1, b=2))
True
## int
>>> is_sequence(123)
False
LIMITATIONS
TBD
"""
return (not hasattr(arg, "strip") and
hasattr(arg, "__iteritems__") or
hasattr(arg, "__iter__"))
def listify(arg):
"""
SYNOPSIS
Wraps scalar objects in a list; passes through lists without alteration.
DESCRIPTION
Normalizes input to always be a list or tuple. If already iterable and
not a string, pass through. If a scalar, make into a one-element list.
If a scalar is wrapped, the same scalar (not a copy) is preserved.
PARAMETERS
arg Object to listify.
RETURNS
list
EXAMPLES
>>> listify(1)
[1]
>>> listify('string')
['string']
>>> listify(1, 2)
Traceback (most recent call last):
...
TypeError: listify() takes exactly 1 argument (2 given)
>>> listify([3, 4,])
[3, 4]
## scalar is preserved, not copied
>>> x = 555
>>> y = listify(x)
>>> y[0] is x
True
## dict is not considered a sequence for this function
>>> d = dict(a=1,b=2)
>>> listify(d)
[{'a': 1, 'b': 2}]
>>> listify(None)
[None]
LIMITATIONS
TBD
"""
if is_sequence(arg) and not isinstance(arg, dict):
return arg
return [arg,]