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

a = []


如何检查a是否为空?

#1 楼

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


使用空的list的隐式布尔值是相当Python的。

评论


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

–詹姆斯·麦克马洪
2011年11月22日6:14



@JamesMcMahon-在显式性和类型灵活性之间进行权衡。通常,“露骨”意味着不做“魔术”的事情。另一方面,“鸭子类型”意味着使用更通用的接口,而不是显式检查类型。因此类似a == []强制特定类型((()== []为False))。在这里,普遍的共识似乎是鸭子输入胜出(实际上,说__nonzero__是测试空度docs.python.org/reference/datamodel.html#object.__nonzero__的接口)

– andrew cooke
2012年5月31日下午14:50

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

–WorshipMe先生
19年3月20日在18:01

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

–sleblanc
19年4月2日在23:55

来自一种声称是某种诗歌的语言,这种机制是纯垃圾。从语义上说,空着和不空着是非常不同的

–埃德温·罗德里格斯(EdwinRodríguez)
4月4日14:03

#2 楼

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


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


Yes: if not seq:
     if seq:

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



评论


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

– BallpointBen
18年5月10日在18:44

Pythonism倡导者会说@BallpointBen应该尽可能隐式地命名变量

–axolotl
18年7月14日在5:35

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

–鲍里斯(Boris)
19年1月4日在23:46

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

–WorshipMe先生
19年3月20日在18:03

尽管有所有Python语言的拥护者,但我与@BallpointBen在一起,因为如果您将seq = [0]错误地写为seq = 0,len(seq)将帮助您捕获错误。人非圣贤孰能。程序员也是。

–aafulei
19-09-26在2:34

#3 楼

我显式地喜欢它:

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


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

评论


检查列表的长度是否等于零,而不是仅检查列表是否为假,这是很丑陋且不合常规的。任何熟悉Python的人都不会以为li就是傻子,也不会在意。如果重要,则应添加注释,而不是更多代码。

–卡尔·史密斯
13年7月9日在13:43



这似乎是不必要的精确测试,它通常比较慢,而且恕我直言。与其检查空的大小,不如不检查空的大小呢?

–约翰B
2014年6月23日14:46



无论如何,这是不好的原因(而在像Python这样的具有强大习语的语言中违反习语通常是不好的)的原因是,它向读者发出信号,表明您正在出于某种原因特别检查长度(例如,因为您想要None)或0引发异常而不是通过)。因此,当您无缘无故地执行操作时,会产生误导,这也意味着当您的代码确实需要进行区分时,该区分是不可见的,因为您在整个源代码中都“哭了起来”。

– aarnert
2014年12月3日,下午2:05

我认为这只是不必要地延长了代码。否则,如果bool(len(li)== 0)为True,为什么不更“明确”呢?

– augurar
2015年1月5日,19:40

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

–ralokt
2015年11月19日下午13:04

#4 楼

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

其他方法不适用于NumPy数组

您需要谨慎使用NumPy数组,因为其他适用于list s或其他标准容器的方法对于NumPy数组失败。我将在下面解释原因,但总之,首选方法是使用size

“ pythonic”方式无效:第1部分

“ pythonic”方式NumPy数组失败,因为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.0False,...),则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检查在此页面上看到的所有情况下都可以正常工作。

评论


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

–加雷斯·拉蒂(Gareth Latty)
15年2月16日在20:47

同意我的观点只是,重要的是要记住,对于x和len(x)惯用语,numpy都选择了中断鸭子类型输入-有时破损很难检测和调试。

–迈克
15年2月16日在21:21

我不知道,对于我来说,如果一个名为len(x)的方法由于假设而没有返回数组长度,则它的名称设计不好。

–道尔顿
15年8月20日在19:54



这个问题与numpy数组无关

–pppery
17年7月31日在18:58

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

–peterhil
17年9月12日在21:22

#5 楼


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

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

a = []


如何检查看看a是否为空?


简短答案:

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

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


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

从文档中开始(并特别注意包含空list,[]):


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


常量被定义为false:False0
任意数字类型为零:0.00jDecimal(0)Fraction(0, 1)''

空序列和集合:()[]{}set()range(0)object.__bool__(self)



数据模型文档:


bool()

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






len()

被调用以实现内置功能__bool__()。应该返回对象的长度,即> = 0的整数。而且,在布尔型上下文中,未定义__len__()方法且其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


我们看到,要么使用内置函数0来比较len(a) == 0来检查长度,要么检查是否为空list的性能远不如使用所记录的语言的内置语法低。

为什么?

对于len检查:

第一个Python具有检查全局变量以查看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


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

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


“因为清单的长度缓存在对象实例标头中,所以这种方法是一种更简单,更快捷的检查方法:

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


来自C源代码和文档的证据


PyObject

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


从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


回应评论:


我要指出的是,对于非空情况也是如此,尽管它与%timeit len(l) != 0然后%timeit l != [] 90.6 ns±8.3 ns相当难看, %timeit not not l 55.6 ns±3.09,not not l 38.5 ns±0.372。但是,尽管速度提高了三倍,但没有人会喜欢if l:。看起来很荒谬。但是速度胜过
我想问题是要及时测试,因为仅%timeit bool(l)就足够了,但令人惊讶的是%timeit l的输出为101 ns±2.64 ns。有趣的是,没有这种惩罚就没有办法胁迫。 %timeit是无用的,因为将不会进行转换。


IPython的not并不是在这里完全没用:

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)


我们可以看到这里每增加一个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 


我们可以在这里看到的是,无论是将实际的q4312079q传递给条件检查还是列表本身,都没有什么区别,并且如果有的话,按原样提供列表也更快。

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

评论


我要指出的是,对于非空情况也是如此,尽管它非常难看,如l = []然后%timeit len(l)!= 0 90.6 ns±8.3 ns,%timeit l!= [] 55.6 ns ±3.09,%timeit不为38.5 ns±0.372。但是,即使速度提高了三倍,也没有任何人会不享受它。看起来很荒谬。但是速度胜出

–格雷戈里·莫尔斯(Gregory Morse)
19年11月28日在5:52

我想问题是用timeit进行测试,因为l:是否足够,但令人惊讶的是%timeit bool(l)的输出为101 ns±2.64 ns。有趣的是,没有这种惩罚就没有办法胁迫。 %timeit l没有用,因为不会进行任何转换。

–格雷戈里·莫尔斯(Gregory Morse)
19年11月28日在6:31

到目前为止最好的答案,谢谢!用魔术方法指出python的真实逻辑,并指出“ Python是用C编写的;它在C级别使用了它的逻辑。用Python编写的任何东西都会变慢。而且可能会变慢几个数量级”是关键。否则,人们会陷入“偏爱”,并且永远不会以一个正确的结论而告终。

– ClementWalter
11月17日15:39



大!这是最好的答案!对于从2020年开始阅读的人(现在是12月,所以差不多是2021年)以及将来。正如我所解释的那样,确定l是否为“ Pythonic”方式和BEST方式,并且还提供了针对每个建议答案计算的时间性能的示例代码,如果len(a)== 0,如果[] = = [],如果很明显,这(如果一个)要快得多,必须实践!

–冰熊
12月19日15:22



#6 楼

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

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


@Daren Thomas


编辑:反对测试
空列表的另一点是False:
多态性呢?您不应该依赖列表作为列表。它应该像鸭子一样嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎地嘎嘎嘎嘎地嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎的鸭子鸭子鸭子
在没有元素的情况下“ False”?


您的duckCollection应该实现__nonzero____len__,因此if a:可以毫无问题地工作。

评论


奇怪的是,虽然[] == False如何计算为False

–information_interchange
19-10-14在3:34

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

– augurar
19-10-20在7:29

#7 楼

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

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

的确,if not a:不能将空列表与None,数字0,空元组或空用户创建的集合类型或空的用户创建的非相当集合类型,或单元素NumPy数组充当带有虚假值的标量,等等。有时,对此加以明确是很重要的。在这种情况下,您知道要明确说明的内容,因此可以进行准确测试。例如,if not a and a is not None:的意思是“除None以外的其他任何虚假信息”,而if len(a) != 0:的意思是“仅空序列-此处除序列外的任何内容都是错误”,依此类推。除了准确测试您要测试的内容之外,这还向读者表明该测试很重要。

但是当您没有任何要明确的内容时,if not a:之外的任何其他内容都会误导读者。当您不重要时,您表示的是同样重要的事情。 (您可能还会使代码的灵活性降低,变慢,变慢等等,但这并不那么重要。)而且,如果您习惯性地这样误导读者,那么当您确实需要区分时,它会被忽略,因为您在代码中一直在“哭狼”。

评论


“当您违反这些习惯用法时,这是一个强烈的信号。”这可能是一个很强的信号,表明您只是在使用由python新手编写的代码,这很多人

– joel
6月17日12:19



#8 楼

为什么要全部检查?
似乎没有人提出质疑,要求您首先测试列表。因为您没有提供其他上下文,所以我可以想象您可能不需要首先进行此检查,但是您不熟悉Python中的列表处理。
我认为,最Python的方式是不检查全部,而是仅处理列表。这样一来,无论是空还是满,它都会做正确的事情。
a = []

for item in a:
    <do something with item>

<rest of code>

的好处是可以处理a的任何内容,而无需专门检查是否为空。如果a为空,则将不执行从属块,并且解释器将进入下一行。
如果确实需要检查数组是否为空,则其他答案就足够了。

评论


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

–阿玛斯·格勒(AmarthGûl)
18年2月2日在14:02

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

–MrWonderful
18年2月17日在19:18

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

–MrWonderful
18年5月22日在22:45

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

– DJK
19年6月24日在22:30

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

–MrWonderful
19年6月27日在4:07

#9 楼

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

JavaScript具有类似的true / falsy概念。

#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或布尔类型转换可能无法完全满足您的期望。

评论


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

– aarnert
2014年12月3日,2:09

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

–加雷斯·拉蒂(Gareth Latty)
15年2月16日在20:54

如果您真的想检查该值是否确实是[]而不是其他类型的虚假内容,那么一定要确定是否要使用== []:,而不是对isinstance进行嘲弄。

– RemcoGerlich
15年7月16日在13:10

虽然==有一些自动强制。我无法确定[]的任何内容。 [] ==()例如返回False。但是例如,frozenset()== set()返回True。因此,至少值得考虑一下在执行== []时是否将某些不需要的类型强制为[](反之亦然)。

– dubiousjim
15年7月16日在13:36

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

–MrWonderful
18-10-12在4:47

#11 楼

从关于真值测试的文档中:

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


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

可以看到,空列表[]是虚假的,因此应执行以下操作将值设为布尔值听起来最有效:

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


评论


@DJ_Stuffy_K断言在单元测试中是什么,一个空列表?只需使用assert(而不是myList)。如果您还想断言该对象是一个列表,则可以使用assertIsInstance()。

–Sнаđошƒаӽ
'18 Sep 1'在5:39

#12 楼

我更喜欢以下内容:

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


评论


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

–卡尔·迈耶
08-09-10 13:42



可读性比a:差,并且更容易破解。请不要这样做。

– devsnd
2012年11月12日11:23



提早()== []也等于false是有好处的。尽管我喜欢这种实现方式读取if if a:涵盖所有情况的方式,但是如果您肯定希望有一个列表,那么您的示例就足够了。

–星
19年3月16日在21:03



需要“更轻松地打破”引用吗?如果a为None时,如果没有中断,则您可能希望对None和[]使用相同的行为,但是如果您明确希望检查一个空列表,则如果a不是,则不会这样做。

– scubbo
8月20日16:14

#13 楼

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

a = [] #the list


1)非常简单的pythonic方式:

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


在Python中,空容器(如列表,元组,集合,字典,变量等)被视为False。可以简单地将列表视为谓词(返回布尔值)。

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

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


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

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


4)另一种愚蠢的方法是使用0exception

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


#14 楼

方法1(首选):

if not a : 
   print ("Empty") 


方法2:

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


方法3:

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


#15 楼

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和[](一个空列表)有关的细微差别。

–HighExodus
11月24日15:59

#16 楼

给出了许多答案,其中很多都很好。我只是想补充一下,对于None和其他类型的空结构,check

not a


也将通过。如果您确实要检查一个空列表,可以执行以下操作:

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


评论


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

– SvenKrüger
19年1月10日,9:40



@SvenKrüger不。运算符,并且在Python中很懒。如果条件after和false为False,则之后将不执行任何操作。

– ElmoVanKielmo
19年2月26日在14:00

#17 楼

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

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(b中的x的布尔(x))为True表示一个空列表

– gberger
18 Mar 5 '18 at 17:27

#18 楼

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


评论


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

–pppery
17年7月12日在15:47

如果我对a:不满意,那是因为如果a不是某种容器,我想要一个例外。 (具有可迭代性还允许迭代器,不能有效地测试其是否为空。)

–戴维斯·鲱鱼
17-09-20在2:40

#19 楼

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

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


评论


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

–MrWonderful
19年4月29日在9:08

#20 楼

您甚至可以尝试使用bool()这样。尽管肯定不太可读,但这是执行此操作的简洁方法。
    a = [1,2,3];
    print bool(a); # it will return True
    a = [];
    print bool(a); # it will return False

我喜欢这种方式,因为检查清单是否为空。
非常方便且有用。

评论


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

–加伦·朗(Galen Long)
17 Mar 10 '17 at 21:42

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

– qneill
17年12月18日在21:13

当a为None时,不利的一面发生。这通常是可以接受的,只是要意识到。

– Lars P
9月29日19:26

#21 楼

print('not empty' if a else 'empty')


更实用:

a.pop() if a else None


和最透明的版本:

if a: a.pop() 


#22 楼


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


希望有帮助。

评论


赞扬还显示了如何检查它是否不为空!这有助于涵盖相反但同样重要的用例

– David Frick
8月16日17:01

#23 楼

只需使用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,例如列表,元组,字典等。通过这些,您可以仅使用is_empty(any_structure)多次调用它。

评论


名称is_empty表示它返回了一些东西。但是,如果确实如此,则应该只是bool(any_structure),而应该使用它(当您完全需要bool时)。

–戴维斯·鲱鱼
17-09-20在2:39

我们为什么要在bool上做一个变体,(也)将消息打印到标准输出中?

–戴维斯·鲱鱼
17年9月20日在3:13

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

– ine那教
17年9月20日在3:45

#24 楼

简单的方法是检查长度等于零。

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


#25 楼

从python3开始,您可以使用

a == []


检查列表是否为空

编辑:这也适用于python2.7。 br />
我不确定为什么会有这么多复杂的答案。
它很清楚和直接

评论


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

– ganeshdeshmukh
18/12/30在10:48

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

–MrWonderful
19年4月29日在8:53

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

– Dheeraj M Pai
4月6日15:44

@MrWonderful我不明白为什么它是pythonic

– Dheeraj M Pai
4月6日15:45

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

– Dheeraj M Pai
4月6日15:47

#26 楼

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

#27 楼

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


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