提问



例如,如果传递以下内容:


a = []


如何检查a是否为空?

最佳参考


if not a:
  print("List is empty")


使用空列表的隐式布尔值是非常pythonic。

其它参考1


pythonic的方法来自PEP 8风格指南(其中表示推荐而表示不推荐):[169]



  对于序列,(字符串,列表,元组),请使用空序列为假的事实。
  


Yes: if not seq:
     if seq:

No:  if len(seq):
     if not len(seq):


其它参考2


我明确地喜欢它:


if len(li) == 0:
    print('the list is empty')


这样100%清楚li是一个序列(列表),我们想测试它的大小。我if not li: ...的问题是它给人的错误印象是li是布尔变量。

其它参考3


其他人似乎将这个问题概括为仅仅是列表,所以我想我会为很多人可能使用的不同类型的序列添加一个警告,特别是因为这是第一个google hit forpython test空数组。


其他方法不适用于numpy数组



你需要小心numpy数组,因为其他适用于list或其他标准容器的方法对于numpy数组都是失败的。我在下面解释原因,但简而言之,首选方法是使用size[170]


pythonic方式不起作用:第1部分



pythonic方式因numpy数组而失败,因为numpy试图将数组转换为bool s的数组,并且if x尝试同时评估所有这些bool s总真值的。但这没有任何意义,所以你得到ValueError:


>>> x = numpy.array([0,1])
>>> if x: print("x")
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()


pythonic方式不起作用:第2部分



但至少上面的情况告诉你它失败了。如果碰巧有一个只有一个元素的numpy数组,那么if语句将正常,因为你不会得到错误。但是,如果那个元素碰巧是0]](或0.0,或false,......),if语句将错误地导致false:


>>> x = numpy.array([0,])
>>> if x: print("x")
... else: print("No x")
No x


但显然x存在并且不是空的!这个结果不是你想要的。


使用len会产生意外结果



例如,


len( numpy.zeros((1,0)) )


返回1,即使数组元素为零。


numpythonic方式



正如scipy FAQ中所解释的那样,在你知道你有一个numpy数组的所有情况下,正确的方法是使用if x.size:[171]


>>> x = numpy.array([0,1])
>>> if x.size: print("x")
x

>>> x = numpy.array([0,])
>>> if x.size: print("x")
... else: print("No x")
x

>>> x = numpy.zeros((1,0))
>>> if x.size: print("x")
... else: print("No x")
No x


如果您不确定它是否是list,numpy数组或其他什么,您可以将此方法与@dubiousjim给出的答案结合起来,以确保对每种类型使用正确的测试。 pythonic,但事实证明,至少在这种意义上,numpy故意破坏了pythonicity。


如果您需要做的不仅仅是检查输入是否为空,并且您正在使用索引或数学运算等其他numpy功能,那么强制输入可能更有效(当然也更常见) 一个numpy数组。快速完成这项工作有一些很好的功能 - 最重要的是numpy.asarray。这会接受你的输入,如果它已经是一个数组就不会做任何事情,或者如果它是一个列表,元组等,你可以将你的输入包装成一个数组,并可选择将它转换为你选择的dtype。所以它很快就会很快,它确保你只是假设输入是一个numpy数组。我们通常只是使用相同的名称,因为转换到数组不会让它回到外面目前的范围:[173] [174]


x = numpy.asarray(x, dtype=numpy.double)


这将使x.size检查在我在此页面上看到的所有情况下都能正常工作。

其它参考4


在真值测试中,空列表本身被认为是假的(参见python文档):[175]


a = []
if a:
     print "not empty"


@Daren Thomas



  编辑:反对测试的另一点
  空列表为False:怎么样
  多态?你不应该依赖
  列表是列表。它应该是
  像鸭子一样嘎嘎叫 - 你怎么样
  让你的duckCollection嘎嘎叫
  没有元素的时候假?



你的duckCollection应该实现__nonzero____len__所以if a:会正常工作。

其它参考5


帕特里克的(接受)答案是正确的:if not a:是正确的方法。哈利霍尔科姆的答案是正确的,这是在PEP 8风格指南。但是,没有任何答案可以解释为什么遵循这个成语是个好主意 - 即使你个人认为它不够明确或者对Ruby用户或其他任何东西感到困惑。


Python代码和Python社区有很强的习惯用法。遵循这些习语使得使用Python的任何人都可以更轻松地阅读代码。当你违反这些习语时,这是一个强烈的信号。


确实if not a:不区分空列表与None,数字0或空元组,或空用户创建的集合类型,或空用户创建的非完全集合类型,或者单元素NumPy数组充当带有假值的标量等等。有时候明确这一点很重要。在这种情况下,你知道你想要明确的,所以你可以测试它。例如,if not a and a is not None:的意思是除了无之外的任何假,而if len(a) != 0:的意思是只有空序列 - 除了序列之外的任何东西都是错误的,依此类推除了测试您想要测试的内容外,这也向读者发出信号,表明此测试非常重要。


但是当你没有任何要明确的东西时,if not a:以外的任何东西都会误导读者。当你不是这样时,你就会发出重要的信号。(你可能也会使代码变得不那么灵活,或者更慢,或者其他什么,但这一切都不那么重要。)如果你习惯性地误导读者,那么当你做需要做出区分时,因为你一直在为你的代码狼哭泣,所以不会引起注意。

其它参考6



  

检查列表是否为空的最佳方法


  
  例如,如果传递以下内容:


a = []

  
  如何检查a是否为空?



简答:



将列表放在布尔上下文中(例如,使用ifwhile语句)。如果它是空的,它将测试False,否则测试True。例如:


if not a:                           # do this!
    print('a is an empty list')


向管理局提出上诉



PEP 8,Python标准库中Python代码的官方Python风格指南,断言:[178]



  对于序列,(字符串,列表,元组),请使用空序列为假的事实。


Yes: if not seq:
     if seq:

No: if len(seq):
    if not len(seq):



我们应该期望标准库代码应该尽可能高效和正确。但为什么会这样,为什么我们需要这个指导?


说明



我经常从经验丰富的Python程序员那里看到这样的代码:


if len(a) == 0:                     # Don't do this!
    print('a is an empty list')


懒惰语言的用户可能会想要这样做:


if a == []:                         # Don't do this!
    print('a is an empty list')


这些在各自的其他语言中是正确的。这在Python中甚至在语义上也是正确的。


但我们认为它不是Pythonic,因为Python通过布尔强制直接在列表对象的接口中支持这些语义。


从文档(并特别注意列入空列表,[]):[179]



  默认情况下,除非其类定义,否则将对象视为true
  返回False__len__()方法的__bool__()方法
  当使用对象调用时返回零。以下是大多数被认为是错误的内置对象:

  
  

      
  • 常量定义为false:NoneFalse

  •   
  • 任何数字类型的零:00.00jDecimal(0)Fraction(0, 1)

  •   
  • 空序列和集合:''()[]{}set()range(0)

  •   



和datamodel文档:



  object.__bool__(self) [180]

  
  被称为实施真值测试和内置操作bool();应该返回FalseTrue。如果未定义此方法,
  如果定义了__len__(),则调用该对象,如果其结果为非零,则认为该对象为真。如果一个类既没有定义__len__()
  并__bool__(),其所有实例都被认为是真实的。







  object.__len__(self) [181]

  
  被调用来实现内置函数len()。应返回对象的长度,整数>=0.此外,未定义__bool__()方法且其__len__()方法返回零的对象在布尔上下文中被视为false。



所以不是这样的:


if len(a) == 0:                     # Don't do this!
    print('a is an empty list')


或这个:


if a == []:                     # Don't do this!
    print('a is an empty list')


做这个:


if not a:
    print('a is an empty list')


做出Pythonic通常在表现上得到的回报:



它有回报吗? (注意,执行等效操作的时间越少越好:)


>>> import timeit
>>> min(timeit.repeat(lambda: len([]) == 0, repeat=100))
0.13775854044661884
>>> min(timeit.repeat(lambda: [] == [], repeat=100))
0.0984637276455409
>>> min(timeit.repeat(lambda: not [], repeat=100))
0.07878462291455435


对于比例,这里是调用函​​数和构造并返回空列表的成本,您可以从上面使用的空白检查的成本中减去:


>>> min(timeit.repeat(lambda: [], repeat=100))
0.07074015751817342


我们看到 用内置函数检查长度len0 或相比,对空列表进行检查比使用所记录的语言的内置语法更低的性能。


为什么?


对于len(a) == 0检查:


首先Python必须检查全局变量以查看len是否被遮蔽。


然后它必须调用函数,加载0,并在Python中进行相等性比较(而不是C):


>>> import dis
>>> dis.dis(lambda: len([]) == 0)
  1           0 LOAD_GLOBAL              0 (len)
              2 BUILD_LIST               0
              4 CALL_FUNCTION            1
              6 LOAD_CONST               1 (0)
              8 COMPARE_OP               2 (==)
             10 RETURN_VALUE


对于[] == [],它必须构建一个不必要的列表然后再次在Python的虚拟机中进行比较操作(而不是C)


>>> dis.dis(lambda: [] == [])
  1           0 BUILD_LIST               0
              2 BUILD_LIST               0
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE


Pythonic方式是一种更简单,更快速的检查,因为列表的长度缓存在对象实例头中:


>>> dis.dis(lambda: not [])
  1           0 BUILD_LIST               0
              2 UNARY_NOT
              4 RETURN_VALUE


来自C源和文档的证据




  PyVarObject [182]

  
  这是PyObject的扩展,它添加了ob_size字段。这仅用于具有一些长度概念的对象。此类型通常不会出现在Python/C API中。它对应于PyObject_VAR_HEAD宏扩展定义的字段。



来自Include/listobject.h中的c源代码:[183]​​]]


typedef struct {
    PyObject_VAR_HEAD
    /* Vector of pointers to list elements.  list[0] is ob_item[0], etc. */
    PyObject **ob_item;

    /* ob_item contains space for 'allocated' elements.  The number
     * currently in use is ob_size.
     * Invariants:
     *     0 <= ob_size <= allocated
     *     len(list) == ob_size


我很喜欢研究这个,我花了很多时间来策划我的答案。如果您认为我要留下一些东西,请在评论中告诉我。

其它参考7


我已经看到以下是首选:


if not a:
    print("The list is empty or null")

其它参考8


为什么要检查?



似乎没有人首先质疑你的需要来测试列表。因为您没有提供额外的上下文,我可以想象您可能不需要首先进行此检查,但不熟悉Python中的列表处理。


我认为最pythonic 的方式是根本不检查,而是只处理列表。这样,无论是空的还是满的,它都会做正确的事情。


a = []

for item in a:
    <do something with item>

<rest of code>


这样可以处理 a 的任何内容,同时不需要对空白进行特定检查。如果 a 为空,则从属块将不会执行,解释器将进入下一行。


如果你确实需要检查数组是否空虚,那么其他答案就足够了。

其它参考9


len()是Python列表,字符串,字符串和集合的O(1)操作。 Python内部跟踪这些容器中的元素数量。[184]


JavaScript有一个类似于truthy/falsy的概念。[185]

其它参考10


我曾写过:


if isinstance(a, (list, some, other, types, i, accept)) and not a:
    do_stuff


被评为-1。我不确定是不是因为读者反对这个策略,或者认为答案并没有提供给我的帮助。我会假装它是后者,因为---无论什么都算pythonic---这是正确的策略。除非你已经排除,或准备处理a例如False的情况,否则你需要一个比if not a:更严格的测试。你可以使用像这个:


if isinstance(a, numpy.ndarray) and not a.size:
    do_stuff
elif isinstance(a, collections.Sized) and not a:
    do_stuff


第一个测试是针对@Mike的回答,上面。第三行也可以替换为:


elif isinstance(a, (list, tuple)) and not a:


如果您只想接受特定类型(及其子类型)的实例,或者:


elif isinstance(a, (list, tuple)) and not len(a):


你可以在没有显式类型检查的情况下离开,但前提是周围的上下文已经确保a是你准备处理的类型的值,或者如果你确定那些类型你不是准备好处理会引发错误(例如,TypeError,如果你调用len对你已经准备好处理它的一个未定义的值。一般来说,pythonic约定似乎是最后一种方式。挤压它像鸭子一样,如果它不知道如何嘎嘎就让它引发一个DuckError。你仍然必须思考关于你正在做什么类型的假设,以及你不准备正确处理的案例是否真的会在正确的地方出错。 Numpy数组是一个很好的例子,只是盲目地依赖len或布尔类型转换可能无法完全按照你期望的那样做。

其它参考11


Python对于空虚的处理非常统一。鉴于以下内容:


a = []

.
.
.

if a:
   print("List is not empty.")
else:
   print("List is empty.")


您只需使用if语句检查列表a,看它是否为空。从我读过和教过的内容来看,这是查看列表或元组是否为空的Pythonic方式。

其它参考12


关于真值测试的文件:[186]


除了此处列出的内容之外的所有值都被视为True



  • None

  • False

  • 任何数字类型的零,例如00.00j

  • 任何空序列,例如''()[]

  • 任何空映射,例如{}

  • 用户定义类的实例,如果类定义__bool__()__len__()方法,则该方法返回整数零或bool值False



可以看出,空列表[]是 falsy ,因此对布尔值执行的操作听起来效率最高:


if not a:
    print('"a" is empty!')

其它参考13


您可以通过以下几种方法检查列表是否为空:


a = [] #the list


1)非常简单的pythonic方式:


if not a:
    print("a is empty")


在Python中,空容器,如列表,元组,集合,dicts,变量等被视为False。可以简单地将列表视为谓词(返回布尔值)。并且True值表示它是非空的。


2)一种非常明确的方式:使用len()查找长度并检查它是否等于0:


if len(a) == 0:
    print("a is empty")


3)或将其与匿名空列表进行比较:


if a == []:
    print("a is empty")


4)另一种愚蠢的方法是使用exceptioniter():


try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")

其它参考14


我使用的一些方法:


if not a:
    print "list is empty"


if len(a) == 0:
    print "list is empty"

其它参考15


我更喜欢以下内容:


if a == []:
   print "The list is empty."


可读,你不必担心调用像len()这样的函数来迭代变量。虽然我不完全确定这样的BigO符号是什么......但是Python如此炽热快,我怀疑它是否重要,除非a是巨大的。

其它参考16


def list_test (L):
    if   L is None  : print 'list is None'
    elif not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test(None)
list_test([])
list_test([1,2,3])


有时候测试None和空虚是有好处的,因为它们是两种不同的状态。上面的代码产生以下输出:


list is None 
list is empty 
list has 3 elements


虽然None是假的,但没有任何价值。所以如果你不想为None分开测试,你就不必这样做了。


def list_test2 (L):
    if not L      : print 'list is empty'
    else: print 'list has %d elements' % len(L)

list_test2(None)
list_test2([])
list_test2([1,2,3])


产生预期


list is empty
list is empty
list has 3 elements

其它参考17


另一种简单的方法可能是


a = []
if len(a) == 0:
  print("Empty")
else:
  print(" Not empty")

其它参考18


你甚至可以尝试像这样使用bool()


    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False


我喜欢这种方式检查清单是否为空。


非常方便和有用。

其它参考19


受@dubiousjim解决方案的启发,我建议使用额外的一般检查,看它是否可以迭代


import collections
def is_empty(a):
    return not a and isinstance(a, collections.Iterable)


注意:字符串被认为是可迭代的。 - 如果要排除空字符串,请添加and not isinstance(a,(str,unicode))


测试:


>>> is_empty('sss')
False
>>> is_empty(555)
False
>>> is_empty(0)
False
>>> is_empty('')
True
>>> is_empty([3])
False
>>> is_empty([])
True
>>> is_empty({})
True
>>> is_empty(())
True

其它参考20


如果要检查列表是否为空;


l = []
if l:
    # do your stuff.


如果要查看天气,列表中的所有值都为空。


l = ["", False, 0, '', [], {}, ()]
if all(bool(x) for x in l):
    # do your stuff.


但是对于空列表,这将是True。


def empty_list(lst):
    if len(lst) ==0:
        return false
    else:
        return all(bool(x) for x in l)


现在你可以使用:


if empty_list(lst):
    # do your stuff.

其它参考21


只需使用is_empty()或make函数: -


def is_empty(any_structure):
    if any_structure:
        print('Structure is not empty.')
        return True
    else:
        print('Structure is empty.')
        return False  


它可以用于任何data_structure,如列表,元组,字典等等。通过这些,您可以使用is_empty(any_structure)多次调用它。

其它参考22


空列表的真值是False,而对于非空列表,它是True

其它参考23


你可以这样做:


lst = []
any(lst)   ##this returns False

其它参考24


一种非正式的方法:


 a = []
 try:
  print(a[-1])
 except IndexError:
  print("List is empty")

其它参考25


查看在Python交互式终端上执行的以下代码。


>>> a = []
>>> if a:
...     print "List is not empty";
... else:
...     print "List is empty"
... 
List is empty
>>> 
>>> a = [1, 4, 9]
>>> if a:
...     print "List is not empty";
... else:
...     print "List is empty"
... 
List is not empty
>>> 

其它参考26


我认为人们建议


if len(list1) == 0:
    print("is a good way")


或len你可以数


if list1.__ len__()==0:
    print("list1 is empty")


你可以再用一种方式


if list1.__ sizeof__() == 40:
    print("list1 is empty")


空列表的大小始终为40。