如何检查列表是否为空?

时间:2008-09-10 06:20:11

标签: python list

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

a = []

如何查看a是否为空?

30 个答案:

答案 0 :(得分:4616)

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

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

答案 1 :(得分:1019)

pythonic方法来自PEP 8 style guide(其中表示“推荐”而表示“不推荐”):

  

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

Yes: if not seq:
     if seq:

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

答案 2 :(得分:633)

我明确地喜欢它:

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

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

答案 3 :(得分:258)

其他人似乎将这个问题概括为仅仅是列表,所以我想我会为很多人可能会使用的不同类型的序列添加一个警告,特别是因为这是第一个谷歌搜索“python test empty array”。

其他方法不适用于NumPy数组

您需要小心使用NumPy数组,因为其他适用于list或其他标准容器的方法对于NumPy数组来说都会失败。我在下面解释原因,但简而言之,preferred method是使用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数组还是其他内容,您可以将此方法与the answer @dubiousjim gives结合使用,以确保为每种类型使用正确的测试。不是很“pythonic”,但事实证明NumPy至少在这个意义上有意破坏了pythonicity。

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

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

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

答案 4 :(得分:132)

  

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

     

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

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   返回__bool__()False方法的__len__()方法   当使用对象调用时返回零。以下是大多数被认为是错误的内置对象:

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

数据模型文档:

  

object.__bool__(self)

     

被要求实施真值测试和内置操作bool();应该返回FalseTrue。如果未定义此方法,   如果已定义,则调用__len__(),如果对象的结果非零,则认为该对象为true。如果一个类既没有定义__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

我很喜欢研究这个,我花了很多时间来策划我的答案。如果您认为我要遗漏某些内容,请在评论中告诉我。

答案 5 :(得分:124)

在真值测试中,空列表本身被视为假(参见python documentation):

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

@Daren Thomas

  

编辑:反对测试的另一点   空列表为False:怎么样   多态?你不应该依赖   列表是列表。应该只是   像鸭子一样嘎嘎叫 - 你好吗?   让你的duckCollection嘎嘎叫   没有元素时'''''

您的duckCollection应该实现__nonzero____len__,以便if a:可以正常运行。

答案 6 :(得分:94)

Patrick's (accepted) answer是对的:if not a:是正确的做法。 Harley Holcombe's answer这是正确的,这是PEP 8风格指南。但是,没有任何答案可以解释为什么遵循这个习惯是一个好主意 - 即使你个人发现它不够明确或者对Ruby用户或其他任何东西感到困惑。

Python代码和Python社区有很强的习惯用法。遵循这些习语使得您的代码更易于阅读Python中的任何人。当你违反这些习语时,这是一个强烈的信号。

if not a:无法区分空列表与None,数字0或空元组,或空用户创建的集合类型,或空用户 - 这是真的创建了非完全集合类型,或者单元素NumPy数组作为带有假值的标量等等。有时候明确这一点非常重要。在这种情况下,您知道您希望明确的,因此您可以对此进行测试。例如,if not a and a is not None:表示&#34;除了无&#34;之外的任何虚假,而if len(a) != 0:表示&#34;只有空序列 - 除了序列之外的任何内容都是错误&#34;,并且等等。除了测试您想要测试的内容之外,这还向读者发出此测试很重要的信号。

但是当你没有任何明确的内容时,if not a:以外的任何内容都会误导读者。当它不是时,你发出重要的信号。 (你可能也会使代码变得不那么灵活,或者更慢,或者其他什么,但这些都不那么重要。)如果你习惯性地误导读者,那么当你 需要做出区分,它会被忽视,因为你已经&#34;哭狼&#34;遍布你的代码。

答案 7 :(得分:61)

为什么要检查?

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

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

a = []

for item in a:
    <do something with item>

<rest of code>

这样可以处理 a 的任何内容,同时不需要对空白进行特定检查。如果 a 为空,则相关块将不会执行,解释程序将进入下一行。

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

答案 8 :(得分:61)

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

JavaScript has a similar notion of truthy/falsy

答案 9 :(得分:35)

我写过:

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

答案 10 :(得分:26)

来自documentation关于真值测试:

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

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

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

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

答案 11 :(得分:21)

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

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

答案 12 :(得分:12)

我更喜欢以下内容:

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

答案 13 :(得分:12)

方法1(首选):

if not a : 
   print ("Empty") 

方法2:

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

方法3:

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

答案 14 :(得分:8)

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进行测试,则不必这样做。

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

答案 15 :(得分:4)

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

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('isActive', CheckboxType::class, array(
            'required' => false
        ))
    $builder->addEventListener(FormEvents::POST_SUBMIT, function(FormEvent $e {
        $entity = $e->getData();
        $form = $e->getForm();
        $isActive = empty($_POST[$form->getName()]['isActive']) ? false : true;
        $entity->setIsActive($isActive);
    });
}

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

None

答案 16 :(得分:3)

如果没有,我们可以使用一个简单的

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

答案 17 :(得分:3)

从python3开始,您可以使用

a == []

检查列表是否为空

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

我不确定为什么会有这么多复杂的答案。 很简单明了

答案 18 :(得分:3)

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

答案 19 :(得分:2)

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

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

答案 20 :(得分:2)

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

更实用:

a.pop() if a else None

答案 21 :(得分:2)

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

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

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

非常方便有用。

答案 22 :(得分:1)

只需使用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)多次调用它。

答案 23 :(得分:1)

检查是否:len(list) == 0返回:True

答案 24 :(得分: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 1
    else: 
        return 0

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

list1 = [] 

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

# Result: "The list is Empty"

希望这会有所帮助。

答案 25 :(得分:0)

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

答案 26 :(得分:0)

空列表的真值是True,而对于非空列表,它是{{1}}。

答案 27 :(得分:0)

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

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

如果要查看天气,列表中的所有值都为空。

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

但是对于空列表,这将是True。

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.

答案 28 :(得分:-1)

使用poptry except子句的愚蠢方式(不推荐):

a = []
try:
    a.pop()
    print('list isn\'t empty')
except:
    print('list is empty')

输出:

list is empty

答案 29 :(得分:-2)

非官方的做法:

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