6

考虑这个简单的功能

def foo(l=[]):
    if not l:  print "List is empty"
    else : print "List is not empty"

现在让我们调用 foo

x=[]
foo(x)
#List is empty

foo('')
#List is empty

但是如果 x=[''] 列表不被认为是空的!!!

x=['']
foo(x)
#List is not empty

问题 -

  1. 为什么空值列表不被视为空?(在变量的情况下,它被认为是空的,例如)

    x=''
    if x:print 'not empty!!'
    else: print 'empty'
    
  2. 如何修改函数 foo() 以便在所有这些情况下将列表视为空:x=[], x=[''],x=['', '']

4

6 回答 6

13

使用内置any()

def foo(l=[]):
    if any(l):
        print 'List is not empty'
    else:
        print 'List is empty'

foo([''])
# List is empty
于 2012-06-25T14:31:22.383 回答
2

在您的示例中,列表真正为空的唯一情况是方括号中没有任何内容。在其他示例中,您有包含各种数量的空字符串的列表。这些只是不同的(在我能想到的所有语言中,都是如此)。

于 2012-06-25T14:31:45.443 回答
1

要回答关于为什么空值列表不被视为空的第一个问题,这是因为它确实包含某些内容,即使这些内容本身是空的。把它想象成一盒空盒子。

下面的代码显示了一种修改函数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
于 2012-06-26T20:10:53.970 回答
1

首先:即使是空字符串也是字符串。包含空字符串的列表仍然包含一个元素。

虽然a=''len = 0 为空,但无论列表如何,它仍然包含一个元素,例如,mylist = [a]与 相同,mylist = ['']但对您来说可能更清楚。以a元素为元素,忽略内容。

要检查列表的元素是否为空,请遍历它们。

def isEmpty(li=[]):
  for elem in li:
    if len(elem) > 0: return false
  return true
于 2012-06-25T14:35:09.183 回答
1

您可以使用对函数 foo 的递归调用来处理嵌套列表。

def foo(l=[]):
    if type(l)==list:
        return any([foo(x) for x in l])
    else:
        return bool(l)
于 2012-06-25T14:58:30.137 回答
0

列表 [''] 确实不是空的。它包含一个空字符串。字符串为空,列表不是。如果要查找这些列表,请检查列表是否为空,如果不是,请检查每个条目是否为 ''。

于 2012-06-25T14:31:56.670 回答