我更喜欢使用isinstance(nl, list),而不是使用type(nl) is list,以获得更通用的算法,允许子类化。
def nl_contains(nl, target):
return isinstance(nl, list) and \
any(item == target or nl_contains(item, target) for item in nl)
这里有一些测试:
>>> nl_contains([1, 2, 3], 1)
True
>>> nl_contains([1, 2, 3], 4)
False
>>> nl_contains([1, [2], 3], 2)
True
>>> nl_contains([1, [2], 3], 4)
False
>>> nl_contains([["ab"], ["cd"]], "a")
False
>>> nl_contains([["ab", [1, 2]], ["cd"]], [1, 2])
True
>>> nl_contains([["ab", [1, 2]], ["cd"]], [1, [2]])
False
如果你想检查子类:
>>> class MyList(list):
... pass
>>> nl_contains(MyList(xrange(3)), 2)
True
在 Python 中,我们使用可迭代对象(list、set、dict)或生成器对象。
要检查对象是否可迭代,请使用:hasattr(iterable, '__iter__')。
例如:
def iterable_contains(iterable, target):
return hasattr(iterable, '__iter__') and \
any(item == target or iterable_contains(item, target) for item in iterable)
一些单元测试:
>>> iterable_contains([1, 2, 3], 1)
True
>>> iterable_contains([1, 2, 3], 4)
False
>>> iterable_contains([1, [2], 3], 2)
True
>>> iterable_contains([1, [2], 3], 4)
False
>>> iterable_contains([["ab"], ["cd"]], "a")
False
>>> iterable_contains([["ab", [1, 2]], ["cd"]], [1, 2])
True
>>> iterable_contains([["ab", [1, 2]], ["cd"]], [1, [2]])
False
>>> class MyList(list):
... pass
>>> iterable_contains(MyList(xrange(3)), 2)
True
>>> iterable_contains({1, 3, (5, 6), 7, 9}, (5,6))
True
>>> iterable_contains(dict(a=5, b=9), 'a')
True
>>> iterable_contains(xrange(10), 5)
True
>>> iterable_contains(xrange(10), 10)
False