ChatGPT解决这个技术问题 Extra ChatGPT

如何检查列表是否为空?

这个问题的答案是社区的努力。编辑现有答案以改进这篇文章。它目前不接受新的答案或交互。

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

a = []

如何检查 a 是否为空?


M
Mateen Ulhaq
if not a:
    print("List is empty")

使用空 listimplicit booleanness 非常符合 Python 风格。


扮演魔鬼的拥护者。我不明白为什么这个成语被认为是pythonic。 “显式优于隐式”,对吗?此检查似乎对正在检查的内容不是很明确。
@JamesMcMahon - 这是明确性和类型灵活性之间的权衡。一般来说,“明确”意味着不做“神奇”的事情。另一方面,“鸭子类型”意味着使用更通用的接口,而不是显式检查类型。所以像 if a == [] 这样的东西会强制使用特定类型(() == []False)。在这里,普遍的共识似乎是鸭子打字胜出(实际上,说 __nonzero__ 是测试空虚的接口 docs.python.org/reference/datamodel.html#object.__nonzero__
这种方法不适用于 numpy 数组.. 所以我认为如果 len(a) == 0 在“鸭子类型”和隐式方面都是可取的。
了解 C 中的数组是否为空的规范方法是取消引用第一个元素并查看它是否为 null,假设数组是 nul 终止的。否则,如果数组的大小很大,将其长度与零进行比较是完全低效的。此外,通常,您不会为空数组分配内存(指针保持为空),因此尝试获取其长度是没有意义的。我并不是说 len(a) == 0 不是一个好方法,只是当我看到它时它不会向我尖叫'C'。
来自一种声称是某种诗歌的语言,这种机制是纯粹的垃圾。从语义上讲,空虚与不存在是非常不同的
H
Harley Holcombe

这样做的 Pythonic 方法来自 PEP 8 style guide

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


如果您希望表明 seq 应该是某种类似列表的对象,则第二种方式似乎更好。
@BallpointBen,Pythonism 倡导者会说,应该尽可能隐含在变量的命名方式中
@BallpointBen 尝试使用 Python 的 type hinting 来指示变量应该是什么。它是在 3.5 中引入的。
numpy 打破了这个成语... seq = numpy.array([1,2,3]) 后跟 if not seq 引发异常“ValueError:具有多个元素的数组的真值不明确。使用 a.any () 或 a.all()"
尽管所有 Pythonic 倡导者,我都支持@BallpointBen,因为如果您错误地将 seq = [0] 写为 seq = 0len(seq) 将帮助您发现错误。人非圣贤孰能。程序员也是如此。
R
Russia Must Remove Putin

我更喜欢它:

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

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


检查列表的长度是否等于 0,而不仅仅是检查列表是否为假,这是丑陋且不符合 Python 标准的。任何熟悉 Python 的人都不会认为 li 是一个布尔值,也不会在意。如果它很重要,您应该添加注释,而不是更多代码。
这似乎是一个不必要的精确测试,它通常更慢并且总是不太可读恕我直言。与其检查空东西的大小,不如只检查它是否为空?
无论如何,这是不好的原因(并且在像 Python 这样具有强习语的语言中违反习语通常是不好的)是它向读者发出信号,表明您出于某种原因专门检查长度(例如,因为您想要 { 1} 或 0 引发异常而不是通过)。所以,当你无缘无故地这样做时,这是一种误导——这也意味着当你的代码确实需要做出区分时,这种区分是不可见的,因为你已经“狼来了”其余的源。
我认为这只是不必要地延长了代码。否则,为什么不用 if bool(len(li) == 0) is True: 更加“明确”呢?
@Jabba 在许多情况下(使用内置数据类型的那些)它将是 O(1),但你不能依赖它。您可能正在使用没有此属性的自定义数据类型。在您编写完此代码之后,您可能还决定稍后添加此自定义数据类型。
M
Mike

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

其他方法不适用于 NumPy 数组

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

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

NumPy 数组的“pythonic”方式失败,因为 NumPy 尝试将数组转换为 bool 数组,并且 if x 尝试一次评估所有这些 bool 以获得某种聚合真值。但这没有任何意义,所以你得到一个 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 数组还是其他东西,您可以将此方法与 the answer @dubiousjim gives 结合使用,以确保对每种类型使用正确的测试。不是很“pythonic”,但事实证明 NumPy 至少在这个意义上故意破坏了 pythonicity。

如果您需要做的不仅仅是检查输入是否为空,并且您正在使用其他 NumPy 功能(如索引或数学运算),那么强制输入 可能更有效(当然也更常见) em> 一个 NumPy 数组。有一些不错的函数可以快速完成此操作 - 最重要的是 numpy.asarray。这将获取您的输入,如果它已经是一个数组则不执行任何操作,或者如果它是一个列表、元组等,则将您的输入包装到一个数组中,并且可以选择将其转换为您选择的 dtype。因此,只要可以,它就非常快,并且它确保您只需假设输入是一个 NumPy 数组。我们通常甚至只使用相同的名称,因为转换为数组不会使其回到当前 scope 之外:

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

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


值得注意的是,这不是 Python 中的缺陷,而是 numpy 故意违反合同 - numpy 是一个具有非常特定用例的库,它对真实性有不同的“自然”定义on an array 是容器的 Python 标准。针对这种情况进行优化是有意义的,就像 pathlib 使用 / 而不是 + 来连接路径 - 这是非标准的,但在上下文中是有意义的。
同意。我的观点是,重要的是要记住 numpy 已经选择为非常常见的 if xlen(x) 习语打破鸭子类型 - 有时这种破损很难检测和调试。
我不知道,对我来说,如果一个名为 len(x) 的方法因为假设而没有返回数组长度,那么它的名字设计得不好。
这个问题与numpy数组无关
@ppperry 是的,最初的问题不是关于 Numpy 数组,但是当使用这些和可能是鸭子类型的参数时,这个问题变得非常相关。
R
Russia Must Remove Putin

检查列表是否为空的最佳方法 例如,如果通过以下内容: a = [] 如何检查 a 是否为空?

简短的回答:

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

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

政治人物 8

PEP 8,Python 标准库中 Python 代码的官方 Python 样式指南,断言:

对于序列(字符串、列表、元组),使用空序列为假的事实。是:如果不是 seq:如果 seq:否:如果 len(seq):如果不是 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 通过布尔强制在列表对象的接口中直接支持这些语义。

docs(并特别注意包含空列表 []):

默认情况下,除非对象的类定义了返回 False 的 __bool__() 方法或返回 0 的 __len__() 方法,否则对象被认为是 true,当与该对象一起调用时。以下是被认为是假的大多数内置对象: 定义为假的常量:无和假。任何数字类型的零:0, 0.0, 0j, Decimal(0), Fraction(0, 1) 空序列和集合:'', (), [], {}, set(), range(0)

和数据模型文档:

object.__bool__(self) 调用实现真值检测和内置操作 bool();应该返回 False 或 True。如果未定义此方法,则调用 __len__()(如果已定义),并且如果对象的结果为非零,则认为该对象为真。如果一个类既没有定义 __len__() 也没有定义 __bool__(),它的所有实例都被认为是真的。

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

然后它必须调用函数,加载 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) != 0 90.6 ns ± 8.3 ns, %timeit l != [] 55.6 ns ± 3.09,%timeit not not l 38.5 ns ± 0.372。但是,尽管速度提高了三倍,但任何人都不会享受不到 l 的乐趣。看起来很荒谬。但是速度胜出我认为问题在于使用 timeit 进行测试,因为如果 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 都会产生一些线性成本。我们希望看到成本,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) != 0 90.6 ns ± 8.3 ns、%timeit l != [] 55.6 ns ± 3.09、%timeit not not l 38.5 ns ± 0.372。但是,尽管速度提高了三倍,但任何人都无法享受 not not l。看起来很荒谬。但速度胜出
我认为问题在于使用 timeit 进行测试,因为仅 if l: 就足够了,但令人惊讶的是 %timeit bool(l) 会产生 101 ns ± 2.64 ns。有趣的是,没有这种惩罚就没有办法强制 bool。 %timeit l 无用,因为不会发生转换。
迄今为止最好的答案,谢谢!用魔法方法指出 Python 的真正逻辑和“Python 是用 C 编写的;它在 C 级别使用它的逻辑。你用 Python 编写的任何东西都会变慢。而且它可能会慢几个数量级”是关键。否则就会陷入“偏好”,永远不会得出正确的结论。
伟大的!这是最好的答案!对于从 2020 年(现在是 12 月,所以几乎是 2021 年)和未来阅读的任何人。执行 if l 是“Pythonic”方式和最佳方式,因为这个人解释得很好,并且还提供了一些为每个建议的答案计算的时间性能示例代码,即 if len(a) == 0if [] == []if a 所以显然,这 (if a) 快得多 &必须练的!
您仍然没有解释为什么应该使用 if ls 而不是 if len(ls)。在 99% 的情况下,我不关心这种小的性能差异,而是更喜欢可读性。 if len(ls) 更易于阅读、更明确,并且在使用不是某种列表的内容时会引发错误,这就是 if len(ls) 更有意义的原因。顺便说一句,我在 not len([])not [] 之间只得到了大约 15% 的性能差异。
t
twasbrillig

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

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

@达伦托马斯

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

您的 duckCollection 应该实现 __nonzero____len__ 以便 if a: 可以正常工作。


奇怪的是 [] == False 将如何评估为 False
@information_interchange 如果要明确检查值的真实性,请使用 bool()bool([]) == False 将按预期计算为 True
@information_interchange 确实不是。考虑一下,如果 [] == False 评估为 True,那么为了一致性,0 == False'' == False 甚至 '' == [] 也应该如此。请注意,布尔上下文中的真实性和测试相等性之间存在区别。恕我直言 Clojure 做到了这一点:只有 False 和 nil 是虚假的。 Python 的规则是合理的。 PHP曾经有邪恶的规则(很久没用了,现在不知道)。
C
Community

Patrick's (accepted) answer 是正确的:if not a: 是正确的做法。 Harley Holcombe's answer 是正确的,这在 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: 之外的任何内容都会误导读者。当它不重要时,你会发出同样重要的信号。 (您也可能使代码变得不那么灵活、变慢或其他原因,但这都不那么重要。)如果您习惯性这样误导读者,那么当您这样做 em> 需要做出区分,它会被忽视,因为你在你的代码中一直在“哭狼”。


“而当你违反那些成语时,这是一个强烈的信号。”这可能是一个强烈的信号,表明您只是在使用由 Python 新手编写的代码,很多人
M
MrWonderful

为什么要检查?

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

足够了。


问题是,检查列表是否为空非常重要,至少对我来说是这样。您是否考虑过 <rest of code> 中是否有可能使用 for 循环结果的脚本?还是直接使用a中的一些值?实际上,如果脚本设计为使用严格控制的输入运行,则检查可能有点不必要。但在大多数情况下,输入会有所不同,并且通常有一个检查会更好。
尊敬的,没有。我考虑的是一个对 Python 了解不够,不知道“if :”是正确答案的人,询问如何检查空列表。然后我注意到很多答案提供了不同的意见,但似乎都没有解决最初的需求。这就是我试图用我的答案做的——让他们在继续之前检查需求。我相信我在回答中明确提出了同样的建议。
@AmarthGûl - 如何从 for 循环中获取结果到要处理的 中的脚本?也许在一个列表中?或者也许是一个字典?如果是这样,同样的逻辑也适用。我不明白变量输入如何在任何类型合理设计的代码中产生任何影响,其中处理空列表将是一个坏主意。
不,您在支票上创建了 O(n) 问题。您唯一考虑在空列表上取得好的结果。答案有效,但在我看来它是次优的
@DJK - 不,我认为你仍然想念它。大概你想用一个列表做某事,如果你有的话。如果它是空的,你会怎么做?早点回来?如果不是空的呢?处理吗?关键仍然是,您可能不需要检查空列表,只需对其进行迭代并执行您要对元素执行的任何操作。如果没有元素,你就会失败。如果有元素,您可以根据需要处理它们。关键是不要使用示例进行空检查,而是根本不检查,只需处理列表。
R
Ry-

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

JavaScript has a similar notion of truthy/falsy


M
Mike

我曾写过:

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

被投票-1。我不确定这是否是因为读者反对该策略或认为答案没有帮助。我会假装是后者,因为——无论什么算作“pythonic”——这是正确的策略。除非您已经排除或准备处理 aFalse 的情况,否则您需要一个比 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 是您准备处理的类型的值,或者您确定您不准备处理的类型handle 将引发您准备处理的错误(例如,如果您在未定义的值上调用 len,则会引发 TypeError)。一般来说,“pythonic”约定似乎是最后一种方式。像鸭子一样挤压它,如果它不知道如何嘎嘎叫,让它引发 DuckError。但是,您仍然必须考虑您所做的类型假设,以及您没有准备好正确处理的情况是否真的会在正确的地方出错。 Numpy 数组是一个很好的例子,仅仅盲目地依赖 len 或布尔类型转换可能不会完全符合您的预期。


很少有你想要接受的 6 种类型的详尽列表,并且对任何其他类型都不灵活。当你需要那种东西时,你可能想要一个 ABC。在这种情况下,它可能是 stdlib ABC 之一,例如 collections.abc.Sizedcollections.abc.Sequence,但它可能是您自己编写并使用 register(list) 的一个。如果您确实有代码,其中重要的是区分空与其他错误,以及区分列表和元组与任何其他序列,那么这是正确的 - 但我不相信您有这样的代码。
人们不喜欢这个的原因是因为在大多数情况下它是完全不必要的。 Python 是一种鸭式语言,这种防御性编码水平积极地阻碍了这一点。 Python 类型系统背后的理念是,只要对象以它需要的方式传入函数,事情就应该工作。通过进行显式类型检查,您会强制调用者使用特定类型,这与语言的本质背道而驰。虽然偶尔这样的事情是必要的(不包括字符串被视为序列),但这种情况很少见,而且几乎总是最好作为黑名单。
如果您真的想检查该值是否恰好是 [] 而不是其他类型的 falsy,那么肯定需要 if a == []:,而不是与 isinstance 混为一谈。
不过,== 有一些自动强制转换。在我的脑海中,我无法为 [] 识别任何内容。 [] == () 例如返回 False。但例如 frozenset()==set() 返回 True。因此,至少值得考虑一下在执行 a == [] 时某些不想要的类型是否可能被强制为 [](反之亦然)。
@RemcoGerlich - isinstance() 仍然比构建一个空列表进行比较更可取。此外,正如另一位指出的那样,相等运算符可能会调用某些类型的隐式转换,这可能是不可取的。没有理由编写“a == []”,并且该代码肯定会在我参与的任何代码审查中被标记为缺陷。使用该语言提供的适当工具不应被视为“胡说八道”,而是“良好的编程技术”。
S
Sнаđошƒаӽ

来自 documentation 的真值测试:

此处未列出的所有值都被视为 True

没有任何

错误的

任何数字类型的零,例如 0、0.0、0j。

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

任何空映射,例如 {}。

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

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

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

@DJ_Stuffy_K 在单元测试中断言什么是空列表?只需使用 assert(not myList)。如果您还想断言对象是 list,则可以使用 assertIsInstance()
B
Boris Verkhovskiy

我更喜欢以下内容:

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

这会变慢,因为您不必要地实例化一个额外的空列表。
这比 if not a: 可读性差,更容易中断。请不要这样做。
前面提出的一个好点() == []也等于false。虽然我喜欢这个实现如何读取 if not a: 涵盖所有情况,但如果您肯定希望得到一个列表,那么您的示例就足够了。
需要“更容易断裂”的引文吗?当 a 为 None 时,if not a 中断 - 您可能希望 None[] 具有相同的行为,但如果您明确想要检查是否为空列表,if not a 不这样做。
@scubbo 如果您真的想明确检查它是否为空列表,请考虑使用 isinstance(a, list) and not a
T
Taufiq Rahman

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

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")

V
Vikrant

方法1(首选):

if not a : 
   print ("Empty") 

方法二:

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

方法三:

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

S
Sunil Lulla

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

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

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

非常方便和有用。


对于那些(像我一样)不知道的人,bool() 将 Python 变量转换为布尔值,因此您可以 store the truthiness or falsiness 的值而无需使用 if 语句。我认为它比简单地使用像接受的答案这样的条件更易读,但我相信它还有其他很好的用例。
这可用于表达式并且更简洁。
不利的一面发生在 a is None 时。这通常是可以接受的,只是需要注意。
T
Tagar
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

恕我直言,这是最好的答案。它解决了测试时与 None[](一个空列表)有关的细微差别。
C
Chris Charles

要检查列表是否为空,您可以使用以下两种方法。但请记住,我们应该避免显式检查序列类型的方式(这是一种不那么 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"

希望这可以帮助。


Upvoted 还展示了如何检查它是否为空!这有助于涵盖相反但同样重要的用例
请注意,第二个可能不适用于其他常见的数组类型对象,例如 numpy 数组。
H
HackerBoss

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

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üger 不。运算符 and 在 Python 中是惰性的。如果 and 之前的条件为 False,则不会执行 and 之后的任何内容。
C
Corman

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

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.

all(bool(x) for x in l) 对于空列表为 True
N
Nice18
print('not empty' if a else 'empty')

更实用一点:

a.pop() if a else None

和最短的版本:

if a: a.pop() 

A
AndreyS Scherbakov

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

过于宽泛;这只是询问一个列表是否为空,而不是某个东西是否是一个空的可迭代对象。
如果我对 if a: 不满意,那是因为如果 a 不是某种容器,我想要一个例外。 (作为一个 iterable 还允许迭代器,它不能有用地测试空性。)
i
ifconfig

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

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

-1 - 为避免混淆,请勿对变量名使用保留字,否则下次尝试调用时可能会出现令人惊讶的行为,例如“list()”......类似于“TypeError: 'list' object is不可调用”或类似的。
V
Vineet Jain

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

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

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


名称 is_empty 表明它返回了一些东西。但如果确实如此,那将只是 bool(any_structure),您应该使用它来代替(您根本需要 bool)。
为什么我们要在 bool 上做一个变体,(也)将消息打印到标准输出?
@DavisHerring 我们总是有两个选择,第一个是使用函数打印,另一个是使用 return bool 变量。选择是你的。我都写了,所以你可以在它们之间进行选择。
A
Ashiq Imran

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

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

T
Trect

从 python3 开始,您可以使用

a == []

检查列表是否为空

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

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


请在不写“if”的情况下提供更多关于它是如何工作的解释?
这不是 pythonic 也不是一个完整的例子。此外,它每次遇到它时都会实例化一个空列表。不要这样做。
@MrWonderful 它不会每次都实例化一个空列表。它只是验证现有列表 a 是否为空。
@MrWonderful 我不明白是什么原因pythonic
@ganeshdeshmukh 如果您使用 a==[] 如果 a 为空,它将在 python 终端上打印 true。否则它将打印 False。您也可以在 if 条件中使用它作为 if(a==[])
i
ifconfig

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

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


V
Vukašin Manojlović

空列表的真值为 False,而非空列表的真值为 True