要回答关于为什么空值列表不被视为空的第一个问题,这是因为它确实包含某些内容,即使这些内容本身是空的。把它想象成一盒空盒子。
下面的代码显示了一种修改函数foo()
以执行您想要的操作(并对其进行测试)的方法。您关于什么是空列表的概念设计起来非常棘手,部分原因是它与语言本身认为空的内容背道而驰。正如您所看到的,根据您的定义确定列表是否为“空”的所有逻辑都已移至一个名为的单独函数empty_list()
中,因为这可能与foo()
必须完成的其余部分几乎没有关系。它并不过分复杂,如果没有其他东西应该为您提供一个良好的起点。
此外,如果它传递的参数不是任何类型的列表或者是一个列表但不包含其他列表或字符串,你没有说它应该做什么,所以写它会引发TypeError
异常 - 某事这类似于大多数内置 Python 函数在发生这种情况时的响应方式。以下是示例代码及其测试输出:
try:
string_type = basestring
except NameError: # probably Python 3.x
string_type = str
class _NULL(object): # unique marker object
def __repr__(self): return '<nothing>'
_NULL = _NULL()
def empty_list(arg=_NULL):
arg = arg if arg is not _NULL else []
if not isinstance(arg, (list, string_type)):
raise TypeError
elif isinstance(arg, string_type):
return not len(arg)
else:
return len(arg) == 0 or all(empty_list(e) for e in arg)
def foo(list_=None):
if list_ is None or empty_list(list_):
print 'list is empty'
else:
print 'list is not empty'
testcases = [
_NULL,
[],
[''],
['', ''],
['', ['']],
['abc'],
['', 'abc'],
[False],
[None],
[0],
[0.0],
[0L],
[0j],
[42],
[{}],
[{'':0}],
[{'a':1}],
False,
None,
0,
0.0,
0L,
0j,
42,
{},
{'':0},
{'a':1},
]
for arg in testcases:
call = 'foo( {!r:s} ) ->'.format(arg)
print '{!s:>20s}'.format(call),
try:
foo() if arg is _NULL else foo(arg)
except TypeError:
print 'illegal argument exception'
这是它使用 Python 2.7 生成的输出:
foo( <nothing> ) -> list is empty
foo( [] ) -> list is empty
foo( [''] ) -> list is empty
foo( ['', ''] ) -> list is empty
foo( ['', ['']] ) -> list is empty
foo( ['abc'] ) -> list is not empty
foo( ['', 'abc'] ) -> list is not empty
foo( [False] ) -> illegal argument exception
foo( [None] ) -> illegal argument exception
foo( [0] ) -> illegal argument exception
foo( [0.0] ) -> illegal argument exception
foo( [0L] ) -> illegal argument exception
foo( [0j] ) -> illegal argument exception
foo( [42] ) -> illegal argument exception
foo( [{}] ) -> illegal argument exception
foo( [{'': 0}] ) -> illegal argument exception
foo( [{'a': 1}] ) -> illegal argument exception
foo( False ) -> illegal argument exception
foo( None ) -> list is empty
foo( 0 ) -> illegal argument exception
foo( 0.0 ) -> illegal argument exception
foo( 0L ) -> illegal argument exception
foo( 0j ) -> illegal argument exception
foo( 42 ) -> illegal argument exception
foo( {} ) -> illegal argument exception
foo( {'': 0} ) -> illegal argument exception
foo( {'a': 1} ) -> illegal argument exception