python - set是否为空 - 判断list为空




如何检查列表是否为空? (20)

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

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

a = []

如何检查a是否为空?

简答:

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

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

上诉到权威

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

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

默认情况下,对象被视为true,除非它的类定义了返回False__len__()方法或者在使用对象调用时返回零的__len__()方法。 以下是大多数被认为是错误的内置对象:

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

和datamodel文档:

object.__bool__(self)

被称为实施真值测试和内置操作bool() ; 应该返回FalseTrue 。 如果未定义此方法,则调用__len__() (如果已定义__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是否被遮蔽。

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

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

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

a = []

如何检查a是否为空?


为什么要检查?

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

这有利于处理a的任何内容,同时不需要对空白进行特定检查。 如果a为空,则依赖块将不会执行,解释器将进入下一行。

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


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

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

Yes: if not seq:
     if seq:

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


一种非正式的方法:

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

从python3开始你可以使用

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

检查列表是否为空

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

我不确定为什么会有这么多复杂的答案。 它非常明确和直截了当


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

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

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

非常方便和有用。


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

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

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

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


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

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

@Daren Thomas

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

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


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

not a

也会传递None和其他类型的空结构。 如果您确实想要检查空列表,可以执行以下操作:

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

帕特里克(接受)的答案是正确的: 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:之外的任何东西都会误导读者。 当事实并非重要时,你就会发出重要的信号。 (你可能也会使代码变得不那么灵活,或者更慢,或者其他什么,但这些都不那么重要。)如果你习惯性地误导读者,那么当你确实需要做出区分时,它会被忽视,因为你的代码一直在“哭狼”。


我使用的一些方法:

if not a:
    print "list is empty"


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

我已经看到以下是首选:

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

我更喜欢以下内容:

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

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


我曾写过:

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是你准备处理的类型的值,或者如果你确定你不准备处理的类型是要准备好处理错误(例如,如果你对未定义的值调用len ,则会出现TypeError )。 一般来说,“pythonic”惯例似乎是最后一种方式。 像鸭子一样挤压它,如果它不知道如何嘎嘎就让它引发DuckError。 你仍然需要考虑你正在做什么类型的假设,以及你不准备正确处理的案例是否真的会在正确的地方出错。 Numpy数组是一个很好的例子,只是盲目地依赖于len或布尔类型转换可能无法完全满足您的期望。


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

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

您可以检查数组的长度是否为零(或不是。)如果数组长度为零,则它为。尝试以下方法:

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

a == []

更实用一点:

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

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




is-empty