如何检查列表是否为空?


3234

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

a = []

如何检查是否a为空?

Answers:


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

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


1127
扮演恶魔的拥护者。我不明白为什么这个成语被认为是pythonic。“明确胜于隐含”,对吗?这项检查对于所检查的内容似乎不太明确。
詹姆斯·麦克马洪

221
@JamesMcMahon-在显式性和类型灵活性之间进行权衡。通常,“露骨”意味着不做“魔术”的事情。另一方面,“鸭子类型”意味着使用更通用的接口,而不是显式检查类型。所以类似的if a == []是强制特定类型(() == []is False)。在这里,一般的共识似乎是,鸭打字胜出(实际上,说__nonzero__是用于测试接口空虚docs.python.org/reference/datamodel.html#object.__nonzero__
安德鲁·库克

38
此方法不适用于numpy数组。.因此,我认为就duck类型和隐式而言,如果len(a)== 0更好。
Mr.WorshipMe,

10
知道C中的数组是否为空的规范方法是,通过取消引用第一个元素并查看其是否为null来假设一个以nul结尾的数组。否则,如果数组的大小很大,则将其长度与零进行比较是完全无效的。同样,通常,您不会为空数组分配内存(指针保持为空),因此尝试获取其长度没有任何意义。我并不是说len(a)== 0并不是一个好方法,当我看到它时,它并不会向我尖叫'C'。
sleblanc

6
@BrennenSprimont,如果它不是以Null结尾的,那么您已经知道了长度,无论是将其存储在单独的变量中还是将数组包装在一些跟踪该长度的容器中。C ++,Java,C#具有此类容器并有效地实现某些“长度”方法。C 没有这样的东西,您必须自己动手。静态分配的C数组只是指向内存空间的指针,该内存空间保证有足够的空间来存储您请求的数据量。C中没有内置任何东西可以让您知道已经填充了多少空间。
sleblanc

1158

这样做的pythonic方法来自PEP 8样式指南(其中Yes表示“推荐”,No表示“不推荐”):

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

Yes: if not seq:
     if seq:

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

49
如果您希望发信号表示seq应该是某种类似于列表的对象,则第二种方法似乎更好。
BallpointBen

5
Python倡导者会说,@BallpointBen应该尽可能隐式地命名变量
axolotl

9
@BallpointBen尝试使用Python的类型提示来表示变量应该是什么。它是在3.5中引入的。
鲍里斯(Boris)

8
numpy打破了这个习惯用法... seq = numpy.array([1,2,3]),如果不是seq,则会引发异常“ ValueError:具有多个元素的数组的真值不明确。请使用a.any ()或a.all()”
Mr.WorshipMe

2
@jeronimo:我相信这是特定于lxml的警告。
哈雷·霍尔科姆

766

我明确喜欢它:

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

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


91
检查列表的长度是否等于零,而不是仅检查列表是否为假,这是丑陋且不合常规的。任何熟悉Python的人都不会以为li是笨蛋,也不会在乎。如果重要,则应添加注释,而不是更多代码。
卡尔·史密斯

21
这似乎是不必要的精确测试,它通常比较慢,并且恕不理解。与其检查空的大小,不如不检查空的大小呢?
约翰B

34
无论如何,这是不好的原因(而违反像Python这样的具有强大习语的语言的习惯通常是不好的)的原因是,它向读者发出信号,您正出于某种原因(例如,因为您想要None0引发异常而不是通过)。因此,当您无缘无故地进行操作时,这会产生误导,这也意味着当您的代码确实需要进行区分时,由于您在整个源代码中都“狼wolf了”,因此区分是不可见的。
abarnert 2014年

18
我认为这只是不必要地延长了代码。否则,为什么不更“明确” if bool(len(li) == 0) is True:
augurar 2015年

11
@Jabba 在许多情况下(使用内置数据类型的情况将为O(1),但是您不能依赖于此。您可能正在使用不具有此属性的自定义数据类型。您可能已经决定在编写此代码之后再添加此自定义数据类型。
ralokt 2015年

324

这是google首次针对“ python测试空数组”和类似的查询命中,再加上其他人似乎在推广问题,不仅限于列表,因此我想为很多人添加另一种类型的序列的警告可能会用。

其他方法不适用于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常见问题解答中所述,在您知道拥有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

如果不确定是a list,NumPy数组还是其他类型,可以将此方法与@dubiousjim给出的答案结合使用以确保对每种类型使用正确的测试。并不是很“ pythonic”,但事实证明,NumPy至少在这种意义上有意破坏了pythonicity。

如果你需要做的不仅仅是检查,如果输入的是空的,而你正在使用其他的功能NumPy的像索引或数学运算,它可能是更有效的(当然更常见)来强制输入一个NumPy的阵列。有一些不错的功能可以快速完成此操作-最重要的是numpy.asarray。这将接受您的输入,如果已经是数组,则不执行任何操作;如果是列表,元组等,则将您的输入包装到数组中,并有选择地将其转换为您选择的dtype。因此,它可以在任何时候都非常快,并且可以确保您只是假设输入是NumPy数组。我们通常甚至只使用相同的名称,因为转换为数组不会使它返回当前范围之外

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

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


62
值得注意的是,这并不是Python中的缺陷,而是故意破坏合同的依据numpy- numpy是一个具有非常特定用例的库,并且它对数组的真实性有不同的“自然”定义。容器的Python标准。针对这种情况进行优化是有意义的,pathlib使用的/是连接路径的方式,而不是+-这是非标准的,但在上下文中是有意义的。
Gareth Latty

9
同意 我的意思是,要记住,重要的是,numpy选择了打破常见的鸭蛋if xlen(x)成语的鸭子输入方式,有时破损很难检测和调试。
迈克

22
我不知道,对我而言,如果因为假设而调用len(x)的方法没有返回数组长度,则它的名称设计错误。
道尔顿

11
这个问题与numpy数组无关
pppery

19
@ppperry是的,最初的问题不是关于Numpy数组的,但是当使用那些(可能是鸭子类型的)参数时,此问题变得非常重要。
peterhil

222

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

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

a = []

如何检查a是否为空?

简短答案:

将列表放在布尔上下文中(例如,使用ifor while语句)。它将测试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中,这甚至在语义上都是正确的。

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

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

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

  • 定义为false的常量:NoneFalse
  • 任何数值类型的零:00.00jDecimal(0)Fraction(0, 1)
  • 空序列和集合:''()[]{}set()range(0)

以及数据模型文档:

object.__bool__(self)

调用实现真值测试和内置操作bool();应该返回FalseTrue。如果未定义此方法,__len__()则调用该方法( 如果已定义),并且如果其结果为非零,则将该对象视为true。如果一个类既未定义,也__len__() 未定义__bool__(),则其所有实例均被视为true。

object.__len__(self)

调用以实现内置函数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

我们看到,无论是与内建函数长度检查len相比,0 检查对空列表是太多比使用语言的内置语法记载高性能的少。

为什么?

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

首先,Python必须检查全局变量以查看是否len有阴影。

然后,它必须调用函数load 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

这是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纳秒±8.3纳秒,%timeit l != []55.6纳秒±3.09,%timeit not not l38.5±NS 0.372。但是,not not l尽管速度提高了三倍,但没有任何人可以享受。看起来很荒谬。但是速度胜出,
我想问题是要及时测试,因为这if l:足够了,但令人惊讶地%timeit bool(l)产生了101 ns±2.64 ns。有趣的是,没有这种惩罚就没有办法胁迫。%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。我们希望看到成本ceteris paribus,即其他所有条件都相等-尽可能将其他所有条件最小化:

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内置的机制,否则这可能会慢几个数量级。


我想指出,这也适用于非空的情况下,虽然它很丑陋与l=[]%timeit len(l) != 090.6纳秒±8.3纳秒,%timeit l != []55.6纳秒±3.09,%timeit not not l38.5±NS 0.372。但是,not not l尽管速度提高了三倍,但没有任何人可以享受。看起来很荒谬。但速度胜出
Gregory Morse

我想问题是要及时测试,因为这if l:足够了,但令人惊讶地%timeit bool(l)产生了101 ns±2.64 ns。有趣的是,没有这种惩罚就没有办法胁迫。 %timeit l是没有用的,因为不会进行任何转换。
格雷戈里·摩尔斯

138

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

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

@达伦·托马斯

编辑:反对测试空列表为假的另一点:多态性怎么样?您不应该依赖列表作为列表。它应该像鸭子一样嘎嘎叫-当它没有元素时,如何使duckCollection嘎嘎叫“ False”?

你duckCollection应该实现__nonzero____len__因此如果一个:没有问题会工作。


奇怪的是,如何[] == False将其评估为False
information_interchange

@information_interchange如果要显式检查值的真实性,请使用bool()bool([]) == False将评估True为预期。
augurar

103

帕特里克(已接受)的答案是正确的:这if not a:是正确的方法。Harley Holcombe的答案是正确的,因为这在PEP 8样式指南中。但是,答案没有一个能解释的是为什么遵循这个习惯用法是一个好主意-即使您个人发现它对于Ruby用户或其他任何人来说都不足够明确或令人困惑。

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

这是真的,if not a:不区分空列表None,或数字0,或空的元组,或空用户创建的集合类型,或空用户创建不-相当-集合类型,或单元素与NumPy阵列充当具有falsey标量值等。有时,明确这一点很重要。而在这种情况下,你知道什么,你想明确一下,这样你就可以测试这一点。例如,if not a and a is not None:表示“除None以外的任何虚假内容”,而if len(a) != 0:表示“仅空序列-此处除序列外的任何其他内容都是错误”,依此类推。除了精确测试要测试的内容外,这还向读者表明该测试很重要。

但是,当您没有什么要明确的内容时,除了if not a:会误导读者,还有其他任何事情。当您不重要时,您是在发出信号。(您也可以使代码不灵活,或慢,或什么的,但是这一切都不太重要。)如果你习惯性地误导这样的读者,那么当你这样做需要做一个区分,它会向任何人声张,因为您在代码中一直在“狼吞虎咽”。


78

为什么要检查?

似乎没有人已经解决了质疑你需要测试在首位名单。因为您没有提供其他上下文,所以我可以想象您可能不需要首先进行此检查,但是您不熟悉Python中的列表处理。

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

a = []

for item in a:
    <do something with item>

<rest of code>

这具有处理任何内容的好处,而不是要求对空虚的特定检查。如果a为空,则将不执行从属块,并且解释器将进入下一行。

如果确实需要检查数组是否为空,则其他答案就足够了。


3
问题是,至少对于我来说,检查列表是否为空非常重要。您是否考虑过其中是否有一些脚本<rest of code>可能使用for循环结果?还是直接在中使用某些值a?确实,如果脚本被设计为在严格控制的输入下运行,则检查可能是不必要的。但是在大多数情况下,输入会有所不同,通常进行检查会更好。
AmarthGûl18年

恭喜,没有。我考虑的是一个对Python不太了解的人,知道“ if <list>:”是正确的答案,并问如何检查空列表。然后我注意到很多答案提供了不同的观点,但是似乎没有一个能够解决最初的需求。这就是我试图回答的问题-让他们在继续之前先检查一下需求。我相信我在回答中也提出了很多建议。
MrWonderful

@AmarthGûl-如何将for循环的结果获取到要处理的<其余代码>中的脚本?在列表中,也许?还是一个命令?如果是这样,则应用相同的逻辑。我不理解变量输入在任何合理设计的代码中如何产生影响,在这种情况下处理空列表将是一个坏主意。
MrWonderful

有点旧了,但是如果您只是检查列表是否为空,那么对于非空列表,您的代码会在OP只是寻找检查操作时一遍又一遍地重复该过程。试想一下,当n接近无穷大时,该代码会出现更糟的情况
。...– DJK

7
@DJK-不,我想您仍然想念它。如果您有一个清单,想必您想用清单来做某事。如果它是空的,您会怎么做?早点回来?如果不为空怎么办?处理吗?重点仍然是,您可能不需要检查一个空列表,只需对其进行迭代,然后对元素进行任何处理即可。如果没有任何元素,您就会失败。如果有元素,则可以根据需要对其进行处理。重点不是使用示例进行空检查,而是根本不检查,只需处理列表即可。
MrWonderful


40

我写过:

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

被投票为-1。我不确定这是否是因为读者反对该策略或认为答案对所提供的内容没有帮助。我会假装是后者,因为-不管什么都算是“ pythonic”-这都是正确的策略。除非您已经排除或准备好处理a例如的案例,否则False您需要的测试比just更具限制性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 否则布尔类型转换可能无法完全满足您的期望。


3
非常难得的是,您要详尽列出要接受的6种类型,而对于其他任何类型都不灵活。当您需要这种东西时,您可能需要ABC。在这种情况下,它可能是stdlib ABC之一,例如collections.abc.Sizedcollections.abc.Sequence,但是它可能是您自己编写并register(list)继续使用的。如果您确实有一些代码,将空值与其他错误值区分开,并且将列表和元组与任何其他序列区分开也很重要,那么这是正确的,但是我不相信您有这样的代码。
abarnert 2014年

13
人们不喜欢它的原因是因为在大多数情况下,这完全是不必要的。Python是一种鸭子式语言,这种防御性编码水平积极地阻碍了这一点。Python类型系统背后的想法是,只要对象按照需要的方式传递给函数,事情就应该起作用。通过执行显式类型检查,您将迫使调用者使用特定类型,这与语言的本质背道而驰。尽管有时这种事情是必要的(将字符串不视为序列),但这种情况很少见,几乎总是最好的黑名单。
Gareth Latty

1
如果您真的想检查该值是否正确,[]而不是其他类型的虚假值,那么一定if a == []:要调用它,而不是用isinstance来嘲弄。
RemcoGerlich 2015年

2
虽然有一些自动强制==。在我的头顶上,我无法识别[][] == ()例如return False。但是例如frozenset()==set()回报True。因此,至少值得考虑一下在执行操作时是否可以将某些不需要的类型强制[](反之亦然)a == []
dubiousjim

@RemcoGerlich-与构造一个空列表进行比较相比,isinstance()仍然更可取。另外,正如另一个指出的那样,相等运算符可能会调用某些类型的隐式转换,这可能是不希望的。我没有理由编写代码“ a == []”,并且在我参与的任何代码审查中,该代码都肯定会被标记为缺陷。 ”,而是“良好的编程技术”。
MrWonderful '18 -10-12

29

从有关真值测试的文档中

除此处列出的值外,所有其他值均被视为 True

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

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

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

@DJ_Stuffy_K断言在单元测试中是什么,一个空列表?只需使用assert(not myList)。如果还想断言对象是a list,则可以使用assertIsInstance()
Sнаđошƒаӽ

24

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

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)另一种愚蠢的做法是使用exceptioniter()

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

20

我更喜欢以下内容:

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

37
这将变慢,因为您不必要地实例化了一个额外的空列表。
卡尔·梅耶

32
这比以前可读性差,if not a:并且更容易破解。请不要这样做。
devsnd 2012年

早先提出的一个好点() == []也等于假。尽管我喜欢此实现如何读取if not a:所有情况的内容,但如果您确实希望获得列表,那么您的示例就足够了。
一颗星

19

方法1(首选):

if not a : 
   print ("Empty") 

方法2:

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

方法3:

if a == [] :
  print ("Empty")

12
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

8

给出了许多答案,其中很多都很好。我只想补充一下

not a

也将通过None和其他类型的空结构。如果您确实要检查一个空列表,可以执行以下操作:

if isinstance(a, list) and len(a)==0:
    print("Received an empty list")

如果a不是列表并且a没有__len__实现方法,则可能引发异常。我建议:if isinstance(obj, list): if len(obj) == 0: print '...'
SvenKrüger19年

4
@SvenKrüger不。运算符and在Python中是懒惰的。and如果条件and为假,则将不执行任何操作。
ElmoVanKielmo

7

我们可以使用简单的方法:

item_list=[]
if len(item_list) == 0:
    print("list is empty")
else:
    print("list is not empty")

5
-1-为避免混淆,请不要在变量名中使用保留字,否则下次尝试调用时可能会出现令人惊讶的行为,例如“ list()”……类似于“ TypeError:'list'object is不可通话”或类似的内容。
MrWonderful

6

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

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.

1
all(在x中的x的布尔(x))对一个空列表为True
gberger

5

受@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

1
泛滥;这只是在问一个列表是否为空,而不是某个东西是否为空的可迭代对象。
pppery

1
如果我不满意if a:,那是因为如果a没有某种容器,我想要一个例外。(成为一个可迭代对象还允许迭代器,该迭代器无法有效地测试其是否为空。)
Davis Herring


4

从python3开始,您可以使用

a == []

检查列表是否为空

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

我不确定为什么会有这么多复杂的答案。很清楚直接


1
请在不写“ if”的情况下提供更多有关其工作原理的解释?
ganeshdeshmukh '18

3
这不是pythonic也不是完整的示例。同样,每次遇到它都会实例化一个空列表。不要这样
MrWonderful

@MrWonderful它不会每次实例化一个空列表。它只是验证现有列表a是否为空。
Tessaracter

@MrWonderful我不明白它的pythonic
成因

如果您使用@ganeshdeshmukh,a==[]如果a为空,它将在python终端上显示true。否则它将打印False。您也可以在if条件下使用它if(a==[])
Tessaracter,

3

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

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

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

非常方便实用。


4
对于像我这样不知道的人,bool()可以将Python变量转换为布尔值,这样您就可以存储值的真实性或虚假性,而不必使用if语句。我认为它比简单地使用诸如接受的答案之类的条件更具可读性,但是我敢肯定还有其他很好的用例。
加伦·隆

这在表达式中可用,并且更简洁。
qneill

3

只需使用is_empty()或使功能类似于:

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

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


3
名称is_empty表明它返回了一些东西。但是,如果确实如此,那应该是bool(any_structure),您应该改用它(您完全需要bool时)。
戴维斯·鲱鱼

4
我们为什么要对此进行修改bool(也可以将消息打印到标准输出)?
戴维斯·鲱鱼

@DavisHerring我们总是有两个选择,第一个是使用函数打印,另一个是使用返回bool变量。选择是你的。我都写了,所以你可以在它们之间进行选择。
Vineet Jain



1

这给我带来了一个特殊的用例:我实际上想要一个函数来告诉我列表是否为空。我想避免在此处编写自己的函数或使用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)))

当然,也不能使用boolif(即if bool(L):),因为它暗示。但是,对于明确需要“不为空”作为函数的情况,bool则是最佳选择。


1

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

def enquiry(list1): 
    if len(list1) == 0: 
        return 0
    else: 
        return 1

# ––––––––––––––––––––––––––––––––

list1 = [] 

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

# Result: "The list is Empty".

第二种方法是more pythonic一种。此方法是一种隐式检查方法,比以前的方法更可取。

def enquiry(list1): 
    if not list1: 
        return True
    else: 
        return False

# ––––––––––––––––––––––––––––––––

list1 = [] 

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

# Result: "The list is Empty"

希望这可以帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.