提问人:Ray 提问时间:9/10/2008 最后编辑:ayhanRay 更新时间:2/15/2023 访问量:4743428
如何检查列表是否为空?
How do I check if a list is empty?
答:
if not a:
print("List is empty")
使用空的隐式布尔值是相当 Python 的。list
评论
if a == []
() == []
False
__nonzero__
)
在真值测试中,空列表本身被认为是假的(参见 python 文档):
a = []
if a:
print("not empty")
编辑:反对测试的另一点 空列表为 False:怎么样 多态性?你不应该依赖 列表就是列表。它应该只是 像鸭子一样嘎嘎叫 - 你好吗 让你的 duckCollection 嘎嘎作响 “False”,当它没有元素时?
你的 duckCollection 应该实现 if a: 可以毫无问题地工作。__nonzero__
__len__
评论
[] == False
bool()
bool([]) == False
True
[] == False
True
0 == False
'' == False
'' == []
我更喜欢以下几点:
if a == []:
print "The list is empty."
评论
if not a:
() == []
if not a:
if not a
None
None
[]
if not a
isinstance(a, list) and not a
Python 的方法是来自 PEP 8 风格指南。
对于序列(字符串、列表、元组),请使用空序列为 false 的事实:
# Correct: if not seq: if seq: # Wrong: if len(seq): if not len(seq):
评论
seq
seq = [0]
seq = 0
len(seq)
len() 是 Python 列表、字符串、字典和集合的 O(1)
操作。Python 在内部跟踪这些容器中的元素数量。
JavaScript 也有类似的真实/虚假概念。
我明确地更喜欢它:
if len(li) == 0:
print('the list is empty')
这样就可以 100% 清楚地知道这是一个序列(列表),我们想测试它的大小。我的问题是它给人一种布尔变量的错误印象。li
if not li: ...
li
评论
li
None
0
if bool(len(li) == 0) is True:
这是“python test empty array”和类似查询的第一次谷歌点击,其他人正在将这个问题推广到列表之外,所以这里有一个警告,很多人使用的不同类型的序列。
其他方法不适用于 NumPy 数组
您需要小心使用 NumPy 数组,因为其他适用于 s 或其他标准容器的方法对于 NumPy 数组会失败。我在下面解释了原因,但简而言之,首选方法是使用 .list
size
“pythonic”方式不起作用:第 1 部分
“pythonic”方式在 NumPy 数组中失败,因为 NumPy 试图将数组转换为 s 数组,并尝试一次评估所有这些 s 以获得某种聚合真值。但这没有任何意义,所以你会得到一个: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
如果您不确定它是否可能是 、 NumPy 数组或其他东西,您可以将这种方法与@dubiousjim给出的答案结合起来,以确保对每种类型使用正确的测试。不是很“pythonic”,但事实证明,NumPy 至少在这个意义上故意破坏了 pythonicity。list
如果您需要做的不仅仅是检查输入是否为空,并且您正在使用其他 NumPy 功能,例如索引或数学运算,那么强制输入为 NumPy 数组可能更有效(当然也更常见)。有一些不错的函数可以快速完成此操作——最重要的是 numpy.asarray
。这将接受您的输入,如果它已经是一个数组,则不执行任何操作,或者将您的输入包装到数组中(如果它是列表、元组等),并可以选择将其转换为您选择的 .因此,只要有可能,它就会非常快,并且它确保您只需假设输入是 NumPy 数组即可。我们通常甚至只使用相同的名称,因为转换为数组不会使其返回当前范围之外:dtype
x = numpy.asarray(x, dtype=numpy.double)
这将使检查在我在此页面上看到的所有情况下都有效。x.size
评论
numpy
numpy
pathlib
/
+
if x
len(x)
我曾写过:
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):
你可以在没有显式类型检查的情况下逃脱,但前提是周围的上下文已经向你保证这是你准备处理的类型的值,或者你确定你不准备处理的类型会引发错误(例如,如果你调用了一个未定义的值),你准备处理。一般来说,“pythonic”约定似乎是最后一种方式。像鸭子一样挤压它,如果它不知道如何嘎嘎叫,就让它发出 DuckError。但是,您仍然必须考虑您正在做出什么类型的假设,以及您没有准备好正确处理的案例是否真的会在正确的地方出错。Numpy 数组就是一个很好的例子,仅仅盲目地依赖或布尔类型转换可能无法完全达到您的期望。a
TypeError
len
len
评论
collections.abc.Sized
collections.abc.Sequence
register(list)
[]
if a == []:
==
[]
[] == ()
False
frozenset()==set()
True
[]
a == []
帕特里克(接受的)答案是正确的:是正确的方法。Harley Holcombe 的回答是正确的,这是在 PEP 8 风格指南中。但是,没有一个答案可以解释为什么遵循这个习惯是一个好主意——即使你个人觉得它不够明确,或者让 Ruby 用户或其他什么人感到困惑。if not a:
Python 代码和 Python 社区具有非常强的习语。遵循这些习语可以使任何有 Python 经验的人更容易阅读您的代码。当你违反这些习语时,这是一个强烈的信号。
确实,不区分空列表和 、数字 0、空元组、空用户创建的集合类型、空的用户创建的不完全集合类型或充当具有错误值的标量的单元素 NumPy 数组等。有时,明确这一点很重要。在这种情况下,你知道你想明确什么,所以你可以准确地测试它。例如,表示“除无之外的任何虚假内容”,而表示“只有空序列,而除了序列之外的任何内容在这里都是错误”,依此类推。除了测试您想要测试的内容外,这也向读者发出信号,表明此测试很重要。if not a:
None
if not a and a is not None:
if len(a) != 0:
但是,当你没有什么可以明确说明的时,除了误导读者之外,其他任何事情都会误导读者。你发出的信号是同样重要的东西,而事实并非如此。(你也可能使代码变得不那么灵活,或者变慢,或者其他什么,但这些都不那么重要了。如果你习惯性地这样误导读者,那么当你确实需要做出区分时,它就会被忽视,因为你一直在你的代码中“哭泣”。if not a:
评论
为什么要检查?
似乎没有人首先质疑您是否需要测试列表。因为你没有提供额外的上下文,我可以想象你可能一开始就不需要做这个检查,但不熟悉 Python 中的列表处理。
我认为最 Python 的方法是根本不检查,而只是处理列表。这样,无论是空的还是满的,它都会做正确的事情。
a = []
for item in a:
# <Do something with item>
# <The rest of code>
这样做的好处是可以处理 a 的任何内容,同时不需要对空进行特定检查。如果 a 为空,则依赖块将不会执行,解释器将进入下一行。
如果您确实需要检查数组是否为空:
a = []
if not a:
# <React to empty list>
# <The rest of code>
就足够了。
评论
<rest of code>
for
a
!a
not a
摘自有关真值测试的文档:
除此处列出的值外,其他所有值都将被考虑在内True
None
False
- 任何数值类型的零,例如 、 、 。
0
0.0
0j
- 任何空序列,例如 , , , .
''
()
[]
- 任何空映射,例如 .
{}
- 用户定义类的实例,如果该类定义了 OR 方法,则当该方法返回整数零或布尔值时。
__bool__()
__len__()
False
可以看出,空列表是虚假的,因此对布尔值执行的操作听起来最有效:[]
if not a:
print('"a" is empty!')
评论
assertIsInstance()。
assert(not myList)
list
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
虽然它一文不值,但那是虚假的。因此,如果您不想将 -ness 的测试分开,则不必这样做。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
评论
None
[]
您甚至可以尝试这样使用。虽然它的可读性较差,但它肯定是一种简洁的执行方式。bool()
a = [1,2,3];
print bool(a); # it will return True
a = [];
print bool(a); # it will return False
我喜欢这种方式,因为检查清单是空的还是空的。
非常方便和有用。
评论
bool()
a is None
您可以通过以下几种方式检查列表是否为空:
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)另一种愚蠢的方法是使用和:exception
iter()
try:
next(iter(a))
# list has elements
except StopIteration:
print("Error: a is empty")
受到 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
检查列表是否为空的最佳方法
例如,如果传递了以下内容:
a = []
如何检查 a 是否为空?
简短的回答:
将列表放在布尔上下文中(例如,使用 or 语句)。它将测试它是否为空,否则。例如:if
while
False
True
if not a: # do this!
print('a is an empty list')
PEP 8
PEP 8 是 Python 标准库中 Python 代码的官方 Python 风格指南,它断言:
对于序列(字符串、列表、元组),请使用空序列为 false 的事实。
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 通过布尔强制直接在列表对象的接口中支持这些语义。
从文档中(并特别注意包含空列表,):[]
默认情况下,除非对象的类定义,否则该对象被视为 true 返回的方法或方法 当与对象一起调用时,返回零。以下是大多数被视为 false 的内置对象:
__bool__()
False
__len__()
- 定义为 false 的常量: 和 .
None
False
- 任何数值类型的零:、、、、
0
0.0
0j
Decimal(0)
Fraction(0, 1)
- 空序列和集合:、、、、、
''
()
[]
{}
set()
range(0)
以及数据模型文档:
调用实现真值测试和内置操作;应返回或 .如果未定义此方法,则调用(如果已定义),如果对象的结果为非零,则认为该对象为 true。如果一个类既不定义也不定义,则它的所有实例都被视为 true。
bool()
False
True
__len__()
__len__()
__bool__()
和
调用以实现内置函数。应返回对象的长度,一个整数 >= 0。此外,未定义方法且其方法返回零的对象在布尔上下文中被视为 false。
len()
__bool__()
__len__()
所以而不是这个:
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
然后它必须调用函数,加载,并在 Python 中进行相等比较(而不是使用 C):0
>>> 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 来源和文档的证据
这是添加字段的扩展。这仅用于具有某种长度概念的对象。此类型通常不会出现在 Python/C API 中。它对应于宏扩展定义的字段。
PyObject
ob_size
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
对评论的回应:
我要指出的是,对于非空情况也是如此,尽管它非常丑陋,例如 90.6 ns ± 8.3 ns、55.6 ns ± 3.09、38.5 ns ± 0.372。但是,尽管速度提高了三倍,但任何人都无法享受。这看起来很荒谬。但是速度胜出,我想问题出
在使用 timeit 进行测试,因为 just 就足够了,但令人惊讶的是产生了 101 ns ± 2.64 ns。有趣的是,如果没有这种惩罚,就没有办法强迫布尔。 是无用的,因为不会发生转换。l=[]
%timeit len(l) != 0
%timeit l != []
%timeit not not l
not not l
if l:
%timeit bool(l)
%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)
我们可以看到,这里每增加一个,就会有一些线性成本。我们希望看到成本,ceteris paribus,也就是说,其他条件都相同 - 所有其他成本都尽可能最小化:not
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
%timeit l != []
%timeit not not l
not not l
if l:
%timeit bool(l)
%timeit l
if l
if len(a) == 0
if [] == []
if a
if a
if ls
if len(ls)
if len(ls)
if len(ls)
not len([])
not []
只需使用 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
bool
bool
如果要检查列表是否为空:
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.
评论
空列表的真值为 ,而对于非空列表,它是 。False
True
简单的方法是检查长度是否等于零。
if len(a) == 0:
print("a is empty")
已经给出了很多答案,其中很多都相当不错。我只是想补充一下,检查
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 '...'
and
and
and
print('not empty' if a else 'empty')
更实用一点:
a.pop() if a else None
和最短的版本:
if a: a.pop()
从 python3 开始,你可以使用
a == []
检查列表是否为空
编辑:这也适用于python2.7。
我不确定为什么有这么多复杂的答案。 它非常清晰和直接
评论
a
pythonic
a==[]
if(a==[])
要检查列表是否为空,可以使用以下两种方法。但请记住,我们应该避免显式检查序列类型的方式(这是一种不太 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".
第二种方式是更 Python 的方式。此方法是一种隐式检查方法,比前一种方法更可取。
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"
评论
我们可以使用一个简单的 if else:
item_list=[]
if len(item_list) == 0:
print("list is empty")
else:
print("list is not empty")
评论
方法 1(首选):
if not a:
print ("Empty")
方法2:
if len(a) == 0:
print("Empty")
方法3:
if a == []:
print ("Empty")
把我带到这里来是一个特殊的用例:我实际上想要一个函数来告诉我列表是否为空。我想避免在这里编写自己的函数或使用 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)))
当然,不要使用 in (i.e., ),因为它是隐含的。但是,对于明确需要“不为空”作为函数的情况,是最佳选择。bool
if
if bool(L):
bool
评论