3231

例如,如果通过以下内容:

a = []

如何检查是否a为空?

4

27 回答 27

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

使用空的隐式布尔list值是非常 Pythonic 的。

于 2008-09-10T06:28:05.147 回答
1372

pythonic 的方法来自PEP 8 style guide

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

# Correct:
if not seq:
if seq:

# Wrong:
if len(seq):
if not len(seq):
于 2008-09-10T10:33:38.113 回答
969

我更喜欢它:

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

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

于 2011-09-05T00:30:30.423 回答
389

这是“python 测试空数组”和类似查询的第一个 google 命中,而且其他人似乎将这个问题概括为不仅仅是列表,所以我想我会为很多人的不同类型的序列添加一个警告可能会使用。

其他方法不适用于 NumPy 数组

您需要小心使用 NumPy 数组,因为其他适用于lists 或其他标准容器的方法对 NumPy 数组无效。我在下面解释原因,但简而言之,首选方法是使用size.

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

NumPy 数组的“pythonic”方式失败了,因为 NumPy 尝试将数组转换为bools 数组,并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

>>> 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 数组。我们通常甚至只使用相同的名称,因为转换为数组不会使其回到当前范围之外:

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

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

于 2012-02-21T16:48:02.057 回答
314

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

例如,如果通过以下内容:

a = []

如何检查 a 是否为空?

简短的回答:

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

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

政治人物 8

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

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

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 通过布尔强制在列表对象的接口中直接支持这些语义。

文档(并特别注意包含空列表,[]):

默认情况下,一个对象被认为是真,除非它的类定义了一个__bool__()返回的方法False或一个__len__()返回零的方法,当与该对象一起调用时。以下是大多数被认为是错误的内置对象:

  • 常量定义为假:NoneFalse
  • 任何数字类型的零:0, 0.0, 0j, Decimal(0),Fraction(0, 1)
  • 空序列和集合:'', (), [], {}, set(),range(0)

和数据模型文档:

object.__bool__(self)

调用实现真值检测和内置运算bool();应该返回FalseTrue。当此方法未定义时 __len__(),如果已定义,则调用该方法,如果其结果为非零,则认为该对象为真。如果一个类既不定义__len__() 也不定义__bool__(),它的所有实例都被认为是真的。

object.__len__(self)

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

所以代替这个:

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被遮蔽。

然后它必须调用函数 load0并在 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

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

Include/listobject.h中的 c 源代码:

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

回复评论:

我要指出的是,对于非空情况也是如此,尽管它非常丑陋,与l=[]当时的%timeit len(l) != 090.6 ns ± 8.3 ns、%timeit l != []55.6 ns ± 3.09、38.5 %timeit not not lns ± 0.372 一样。not not l但是,尽管速度提高了三倍,但没有人会享受。看起来很荒谬。但是速度胜出
我认为问题在于使用 timeit 进行测试,因为这if l:已经足够但令人惊讶地%timeit bool(l)产生 101 ns ± 2.64 ns。有趣的是,没有这种惩罚就没有办法强制 bool。%timeit l是无用的,因为不会发生转换。

IPython 魔法,%timeit在这里并非完全没用:

In [1]: l = []                                                                  

In [2]: %timeit l                                                               
20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [3]: %timeit not l                                                           
24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [4]: %timeit not not l                                                       
30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

我们可以看到这里每增加一个成本都有一点线性成本not。我们希望看到成本,在其他条件不变的情况下,即所有其他条件都相同——所有其他条件都尽可能地最小化:

In [5]: %timeit if l: pass                                                      
22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [6]: %timeit if not l: pass                                                  
24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [7]: %timeit if not not l: pass                                              
23.4 ns ± 0.793 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

现在让我们看一下非空列表的情况:

In [8]: l = [1]                                                                 

In [9]: %timeit if l: pass                                                      
23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [10]: %timeit if not l: pass                                                 
23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [11]: %timeit if not not l: pass                                             
26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

我们在这里可以看到,将实际值传递bool给条件检查还是列表本身几乎没有什么区别,如果有的话,按原样提供列表会更快。

Python 是用 C 编写的;它在 C 级别使用其逻辑。你用 Python 写的任何东西都会变慢。除非您直接使用 Python 内置的机制,否则它可能会慢几个数量级。

于 2017-08-20T03:50:58.437 回答
161

在真值测试中,空列表本身被认为是错误的(请参阅python 文档):

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

@达伦托马斯

编辑:反对将空列表测试为 False 的另一点:多态性呢?您不应该依赖列表作为列表。它应该像鸭子一样嘎嘎叫——当它没有元素时,你如何让你的鸭子集合嘎嘎叫“假”?

您的 duckCollection 应该实现if a:__nonzero__左右__len__将毫无问题地工作。

于 2008-09-10T06:31:22.597 回答
115

帕特里克(已接受)的答案是正确的:if not a:是正确的方法。Harley Holcombe 的回答是正确的,这在 PEP 8 风格指南中。但是没有一个答案能解释为什么遵循这个成语是一个好主意——即使你个人发现它不够明确或让 Ruby 用户感到困惑或其他什么。

Python 代码和 Python 社区都有非常强大的习语。遵循这些习惯用法可以让任何有 Python 经验的人更容易阅读您的代码。当你违反这些成语时,这是一个强烈的信号。

确实if not a:不区分空列表与None,或数字 0,或空元组,或空的用户创建的集合类型,或空的用户创建的 not-quite-collection 类型,或作为标量的单元素 NumPy 数组价值观等。有时,明确这一点很重要。在这种情况下,您知道明确说明的内容,因此您可以对其进行测试。例如,if not a and a is not None:表示“除了 None 之外的任何错误的东西”,而if len(a) != 0:表示“只有空序列——除了序列之外的任何东西都是错误的”,等等。除了准确地测试您想要测试的内容之外,这还向读者表明该测试很重要。

但是当你没有什么要明确说明的时候,除了if not a:误导读者之外的任何东西。当它不重要时,你会发出同样重要的信号。(你也可能使代码变得不那么灵活,或者更慢,或者其他什么,但这都不那么重要。)如果你习惯性地这样误导读者,那么当你确实需要做出区分时,它会被忽视,因为你在你的代码中一直在“哭狼”。

于 2014-12-03T02:21:29.383 回答
98

为什么要检查?

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

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

如果您确实需要检查数组是否为空:

a = []

if !a:
    <react to empty list>

<rest of code>

足够了。

于 2015-10-06T19:25:34.767 回答
75

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

JavaScript也有类似的truthy/falsy 概念

于 2008-09-15T05:50:48.547 回答
53

我曾写过:

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或者布尔类型转换可能不会完全符合您的预期。

于 2012-05-31T14:35:05.343 回答
37

我更喜欢以下内容:

if a == []:
   print "The list is empty."
于 2008-09-10T06:43:14.393 回答
37

来自关于真值测试的文档:

此处列出的值以外的所有值都被考虑True

  • None
  • False
  • 任何数字类型的零,例如0, 0.0, 0j
  • 任何空序列,例如'', (), [].
  • 任何空映射,例如{}.
  • 用户定义类的实例,如果该类定义了一个__bool__()or__len__()方法,当该方法返回整数零或 bool 值时False

可以看出,空列表[]falsy,所以对布尔值执行的操作听起来最有效:

if not a:
    print('"a" is empty!')
于 2016-01-01T18:18:58.703 回答
34

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

a = [] #the list

1)非常简单的pythonic方式:

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

在 Python 中,空容器(如列表、元组、集合、字典、变量等)被视为False. 可以简单地将列表视为谓词(返回布尔值)。一个True值将表明它是非空的。

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

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

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

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

4)另一种愚蠢的做法是使用exceptionand iter()

try:
    next(iter(a))
    # list has elements
except StopIteration:
    print("Error: a is empty")
于 2016-11-28T14:18:03.180 回答
29

方法1(首选):

if not a : 
   print ("Empty") 

方法二:

if len(a) == 0 :
   print( "Empty" )

方法三:

if a == [] :
  print ("Empty")
于 2019-02-09T23:59:54.157 回答
24

你甚至可以尝试bool()像这样使用。尽管它的可读性肯定较低,但它是执行此操作的一种简洁方式。

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

我喜欢这种方式,因为检查列表是否为空。

非常方便和有用。

于 2016-09-13T11:53:56.763 回答
18
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-ness,则不必这样做。

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
于 2016-04-13T21:55:32.423 回答
15

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

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

如果要检查列表中的所有值是否为空。但是它将是True一个空列表:

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

如果您想同时使用这两种情况:

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.
于 2018-03-05T11:30:01.000 回答
15

已经给出了很多答案,其中很多都很好。我只是想补充一下支票

not a

还将传递 forNone和其他类型的空结构。如果你真的想检查一个空列表,你可以这样做:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")
于 2018-10-12T04:01:59.470 回答
15

要检查列表是否为空,您可以使用以下两种方法。但请记住,我们应该避免显式检查序列类型的方式(这是一种不那么 Python的方式):

def enquiry(list1):
    return len(list1) == 0

# ––––––––––––––––––––––––––––––––
      
list1 = [] 

if enquiry(list1): 
    print("The list isn't empty") 
else: 
    print("The list is Empty") 

# Result: "The list is Empty".

第二种方式是一种更 Pythonic的方式。这种方法是一种隐式检查方法,比前一种方法更可取。

def enquiry(list1): 
    return not list1

# ––––––––––––––––––––––––––––––––
      
list1 = [] 

if enquiry(list1): 
    print("The list is Empty") 
else: 
    print("The list isn't empty") 

# Result: "The list is Empty"

希望这可以帮助。

于 2018-12-26T00:05:06.807 回答
11

受到@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
于 2017-03-29T02:58:02.140 回答
11
print('not empty' if a else 'empty')

更实用一点:

a.pop() if a else None

和最短的版本:

if a: a.pop() 
于 2018-11-03T02:23:02.233 回答
11

我们可以使用一个简单的 if else:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")
于 2019-01-06T19:15:13.933 回答
8

只需使用 is_empty() 或制作如下函数:-

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

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

于 2017-08-26T19:04:05.863 回答
8

简单的方法是检查长度是否为零。

if len(a) == 0:
    print("a is empty")
于 2018-10-12T02:59:58.930 回答
6

从 python3 开始,您可以使用

a == []

检查列表是否为空

编辑:这也适用于 python2.7..

我不知道为什么会有这么多复杂的答案。它非常清晰明了

于 2018-11-06T09:55:45.857 回答
5

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

于 2018-05-16T04:13:04.293 回答
5

把我带到这里的是一个特殊的用例:我实际上想要一个函数来告诉我列表是否为空。我想避免在这里编写自己的函数或使用 lambda 表达式(因为它看起来应该足够简单):

foo = itertools.takewhile(is_not_empty, (f(x) for x in itertools.count(1)))

当然,有一种非常自然的方法可以做到这一点:

foo = itertools.takewhile(bool, (f(x) for x in itertools.count(1)))

当然,不要使用in bool( ifie, if bool(L):),因为它是隐含的。但是,对于明确需要“不为空”作为函数的情况,bool这是最好的选择。

于 2019-04-24T15:07:03.550 回答