例如,如果通过以下内容:
a = []
如何检查a
是否为空?
#1楼
我写过:
if isinstance(a, (list, some, other, types, i, accept)) and not a:
do_stuff
被投票为-1。 我不确定这是否是因为读者反对该策略或认为答案对所提供的内容没有帮助。 我会假装是后者,因为-不管什么都算是“ pythonic”-这都是正确的策略。 除非您已经排除或准备处理a
为False
(例如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
或布尔类型转换可能无法完全满足您的期望。
#2楼
帕特里克(已接受)的答案是正确的: 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:
以外的其他任何内容都会误导读者。 当您不重要时,您是在发出信号。 (您可能还会使代码的灵活性降低,变慢,变慢等等,但这并不那么重要。)而且,如果您习惯性地这样误导读者,那么当您确实需要区分时,它会被忽略,因为您在代码中一直在“狼吞虎咽”。
#3楼
为什么要检查?
似乎没有人已经解决了质疑你需要测试在首位名单。 因为没有提供其他上下文,所以我可以想象您可能不需要首先进行此检查,但是您不熟悉Python中的列表处理。
我认为最Python的方式是根本不检查,而只是处理列表。 这样,无论是空还是满,它都会做正确的事情。
a = []
for item in a:
<do something with item>
<rest of code>
这具有处理的任何内容,而无需对空虚特定检查的好处。 如果a为空,则将不执行从属块,并且解释器将进入下一行。
如果确实需要检查数组是否为空,则其他答案就足够了。
#4楼
从有关真值测试的文档中 :
除此处列出的值外,所有其他值均视为True
-
None
-
False
- 任何数值类型的零,例如,
0
,0.0
,0j
。 - 任何空序列,例如
''
,()
,[]
。 - 任何空映射,例如
{}
。 - 用户定义类的实例,如果该类定义了
__bool__()
或__len__()
方法,则该方法返回整数零或布尔值False
。
可以看出,空列表[]
是虚假的 ,因此对布尔值执行的操作听起来最有效:
if not a:
print('"a" is empty!')
#5楼
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
是falsy。 因此,如果您不想单独测试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
#6楼
您甚至可以尝试使用bool()这样
a = [1,2,3];
print bool(a); # it will return True
a = [];
print bool(a); # it will return False
我喜欢这种方式来检查列表是否为空。
非常方便和有用。
#7楼
您可以通过以下几种方法检查列表是否为空:
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")
#8楼
受@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
#9楼
检查列表是否为空的最佳方法
例如,如果通过以下内容:
a = []
如何检查a是否为空?
简短答案:
将列表放在布尔上下文中(例如,使用if
或while
语句)。 如果为空,它将测试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中,这甚至在语义上都是正确的。
但是我们认为它不是Python语言,因为Python通过布尔强制转换直接在列表对象的界面中支持这些语义。
在文档中 (并特别注意包含空列表[]
):
缺省情况下,对象被认为是真实的,除非它的类或者定义
__bool__()
方法,该方法返回False
或__len__()
方法返回零,当与对象调用。 以下是大多数被认为是错误的内置对象:
- 定义为false的常量:
None
和False
。- 任何数值类型的零:
0
,0.0
,0j
,Decimal(0)
Fraction(0, 1)
- 空序列和集合:
''
,()
,[]
,{}
,set()
,range(0)
以及数据模型文档:
调用以实现真值测试和内置操作
bool()
; 应该返回False
或True
。 如果未定义此方法,则调用__len__()
(如果已定义),并且如果其结果为非零,则认为该对象为true。 如果一个类__len__()
或__bool__()
,则其所有实例均被视为true。
和
调用以实现内置函数
len()
。 应该返回对象的长度,即> = 0的整数。而且,在布尔上下文中,__len__()
__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源代码和文档的证据
这是
PyObject
的扩展,添加了ob_size
字段。 这仅用于具有长度概念的对象。 此类型通常不会出现在Python / C API中。 它对应于通过扩展PyObject_VAR_HEAD
宏定义的字段。
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
我很喜欢对此进行研究,并且花了很多时间来整理答案。 如果您认为我有遗漏,请在评论中让我知道。
#10楼
只需使用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)
多次调用它。
#11楼
如果要检查列表是否为空;
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.
#12楼
空列表的真值是False
而非空列表的真值是True
。
#13楼
一种简单的方法是检查长度等于零。
if len(a) == 0:
print("a is empty")
#14楼
给出了许多答案,其中很多都很好。 我只想补充一下
not a
也将通过None
和其他类型的空结构。 如果您确实要检查一个空列表,可以执行以下操作:
if isinstance(a, list) and len(a)==0:
print("Received an empty list")
#15楼
print('not empty' if a else 'empty')
实用一点:
a.pop() if a else None
和最透明的版本:
if a: a.pop()
#16楼
从python3开始,您可以使用
a == []
检查列表是否为空
编辑:这也适用于python2.7。
我不确定为什么会有这么多复杂的答案。 很清楚直接
#17楼
if not a:
print("List is empty")
使用空list
的隐式布尔值是非常Python的。
#18楼
空列表本身在真实值测试中被认为是错误的(请参阅python文档 ):
a = []
if a:
print "not empty"
@达伦·托马斯
编辑:反对测试空列表为假的另一点:多态性怎么样? 您不应该依赖列表作为列表。 它应该像鸭子一样嘎嘎叫-当它没有元素时,如何使duckCollection嘎嘎叫“ False”?
您的duckCollection应该实现__nonzero__
或__len__
因此if a:可以正常工作。
#19楼
我更喜欢以下内容:
if a == []:
print "The list is empty."
#20楼
这样做的pythonic方法来自PEP 8样式指南 (其中Yes表示“推荐”, No表示“不推荐”):
对于序列(字符串,列表,元组),请使用空序列为假的事实。
Yes: if not seq: if seq: No: if len(seq): if not len(seq):
#21楼
要检查列表是否为空,可以使用以下两种方法。 但是请记住,我们应该避免显式检查序列或列表的方式(这是一种
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"
希望这可以帮助。
#22楼
我们可以使用简单的方法:
item_list=[]
if len(item_list) == 0:
print("list is empty")
else:
print("list is not empty")
#23楼
检查是否: len(list) == 0
返回: True
#24楼
方法1(首选):
if not a :
print ("Empty")
方法2:
if len(a) == 0 :
print( "Empty" )
方法3:
if a == [] :
print ("Empty")
#25楼
这给我带来了一个特殊的用例:我实际上想要一个函数来告诉我列表是否为空。 我想避免在此处编写自己的函数或使用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楼
len()
是用于Python列表,字符串,字典和集合的O(1)操作 。 Python在内部跟踪这些容器中元素的数量。
JavaScript 有一个true / falsy的类似概念 。
#27楼
我明确喜欢它:
if len(li) == 0:
print('the list is empty')
这样,就可以100%清楚地知道li
是一个序列(列表),我们要测试其大小。 if not li: ...
我的问题是if not li: ...
会给人一种错误的印象,即li
是一个布尔变量。
#28楼
这是google首次针对“ python测试空数组”和类似的查询,再加上其他人似乎在推广问题,不仅仅是列表,所以我想为很多人添加另一种类型的序列的警告可能会用。
其他方法不适用于NumPy数组
您需要注意NumPy数组,因为其他适用于list
或其他标准容器的方法对NumPy数组均无效。 我在下面解释了原因,但总之, 首选方法是使用size
。
“ pythonic”方式无效:第1部分
NumPy数组的“ pythonic”方法失败,因为NumPy尝试将数组转换为bool
的数组,并且if x
尝试一次为某种聚合真值求值所有这些bool
s。 但这没有任何意义,因此您会遇到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
在没有错误的意义上, 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常见问题解答中所述,在您知道拥有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
检查在我在此页面上看到的所有情况下均有效。