>>> 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
确实,if not a:并没有区分空列表和None,或数字0,或空元组,或空用户创建的集合类型,或空用户创建的不完全集合类型,或充当带有假值的标量的单元素NumPy数组,等等。有时明确这一点很重要。在这种情况下,你知道什么你想明确,所以你可以准确地测试。例如,if not a and a is not None:表示“除了无之外的任何错误”,而if len(a) != 0:表示“只有空序列-并且除了序列之外的任何东西在这里都是错误的”,等等。除了测试你想要测试的内容之外,这也向读者表明这个测试很重要。
但是当你没有任何东西需要明确的时候,除了if not a:之外的任何东西都会误导读者。当你不重要的时候,你在发出同样重要的信号。(你也可能会让代码变得不那么灵活,或者更慢,或者其他什么,但这一切都不那么重要。)如果你习惯性地这样误导读者,那么当你做需要做出区分的时候,它就会被忽视,因为你的代码到处都是“狼来了”。
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 Nonelist is emptylist 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])
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
对评论的答复:
我想指出,这也适用于非空情况,尽管它非常丑陋,因为l=[]然后%timeit len(l) != 0 90.6 ns±8.3 ns,%timeit l != [] 55.6 ns±3.09,%timeit not not l 38.5 ns±0.372。但是,尽管速度增加了三倍,但没有人会喜欢not not l。它看起来很荒谬。但是速度胜出了 我想问题是测试时间,因为只有if l:就足够了,但令人惊讶的是%timeit bool(l)产生101 ns±2.64 ns。有趣的是,没有这种惩罚就没有办法强制bool。%timeit l是无用的,因为不会发生转换。
IPython魔法,%timeit,在这里并非完全无用:
In [1]: l = []
In [2]: %timeit l20 ns ± 0.155 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
In [3]: %timeit not l24.4 ns ± 1.58 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [4]: %timeit not not l30.1 ns ± 2.16 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [5]: %timeit if l: pass22.6 ns ± 0.963 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [6]: %timeit if not l: pass24.4 ns ± 0.796 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [7]: %timeit if not not l: pass23.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: pass23.7 ns ± 1.06 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [10]: %timeit if not l: pass23.6 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [11]: %timeit if not not l: pass26.3 ns ± 1 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
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".
第二种方法是更多Pythonic方法。这种方法是一种隐式检查方法,比前一种方法更可取。
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"