Python之禅:显式优于隐式。

9

我试图理解在Python的上下文中,'implicit'和'explicit'的真正含义。

a = []

# my understanding is that this is implicit
if not a:
   print("list is empty")

# my understanding is that this is explicit
if len(a) == 0:
   print("list is empty")

我试图遵循Python之禅的规则,但是我想知道这是否适用于这种情况,或者是否我考虑过度了?


1
为什么是 a?为什么是 list?打错了吗? - Mad Physicist
确实有点奇怪。将其更改为 == 0。在这种情况下,“len(a) == 0”听起来比“not a”更明确,但它们都被认为是明确的吗? - sir_chocolate_soup
1
“if not a” 明确地检查了变量 “a” 是否为假值(在这种情况下为空)。而“if len(a)==0” 则明确地检查了变量 “a” 的长度是否等于零。 - khelwood
数学思维:∅代表空集,你可以认为它什么都没有。如果某物不存在,那就不是真的存在。在“列表中是否有任何项?”和“列表中的项数是否恰好为零?”之间存在一定的差距。在大多数情况下,你可能更关心第一个问题而不是第二个问题,尽管它们是等价的。 - mazunki
因为它是一种弱类型语言,所以这是可笑的。 - Aminos
显示剩余2条评论
3个回答

12
这两个语句的语义非常不同。请记住Python是动态类型的。
对于 a = [] 的情况,not alen(a) == 0 是等效的。一个有效的替代方案可能是检查 not len(a)。在某些情况下,您甚至可能希望通过执行 a == [] 来检查空和列表状态。
但是,a 可以是任何东西。例如,a = None。检查 not a 没问题,并且将返回 True。但是,len(a) == 0 将完全不好。相反,您将得到 TypeError: object of type 'NoneType' has no len()。这是一个完全有效的选项,但是这些if语句执行非常不同,您必须选择需要哪一个。
(几乎)所有Python中的对象都有一个__bool__ 方法,但并不是所有对象都有__len__。您必须根据情况决定使用哪一个。需要考虑以下事项:
- 您是否已经验证了 a 是否是序列? - 您需要吗? - 如果在非序列上运行,则是否会使if语句崩溃? - 您是否希望将其他falsy对象处理为如果它们是空列表?
请记住,使代码看起来漂亮的次要因素是正确地完成工作。

谢谢你的解释!看起来我更关注的是可读性而不是背后的意思和最初的目的。 - sir_chocolate_soup

4

虽然这个问题很旧,但我想提供一些观点。

在动态语言中,我的偏好是始终描述变量的期望类型和目标,以提供更有目的性的理解。然后利用语言的知识使代码简洁,并尽可能增加可读性(在 Python 中,空列表的布尔结果为 false)。因此,代码如下:

lst_colours = [] 

if not lst_colours: 
  print("list is empty")

使用变量进行非常具体的检查更好地传达含义。

lst_colours = []
b_is_list_empty = not lst_colours

if b_is_list_empty: 
  print("list is empty")

在代码库中多次检查列表是否为空是一件很常见的事情。因此最好将这种操作放在一个单独的文件助手函数库中。从而隔离常见的检查,并减少代码重复。

lst_colours = []

if b_is_list_empty(lst_colours): 
  print("list is empty")


def b_is_list_empty (lst):
  ......

最重要的是,尽可能地增加含义,在公司内部达成一致的标准,以选择如何处理简单的事情,例如变量命名和隐式/显式代码选择。


这是唯一一个实际解决此问题的禅宗方面的答案。我们正在问的条件问题是“列表中是否有任何项目?”这个问题和“列表中的项目计数是否为零?”之间存在微妙的差别,如果您制作了一个特定情况的自定义子类,则可能会很重要。使用像is_empty(some_list)这样的函数表达了读者的意思,这正是我们想要的。更好的方法是让Python中的列表具有list.is_empty作为动态属性。接受False等同于空集∅也是可能的。 - mazunki

2
尝试思考以下内容:
if not a:
    ...

作为的简写:
if len(a) == 0:
    ...

我认为这不是Python“显式”优于“隐式”原则的一个好例子。这主要是为了可读性而做的。并不是第二个更差,第一个更好。只是第一个更熟练。如果人们理解Python中列表的布尔性质,我认为第一个更容易阅读,在Python中可读性很重要。

3
一个并不比另一个更加熟练。它们有不同的含义。其中一个仅适用于序列,而另一个则不适用,例如。知道它们之间的差异就是技能所在。否则,这将成为一个基于观点的问题。 - Mad Physicist
好观点,但我想这是一个主观看法。我想指出这更多是为了可读性而不是显式与隐式的演示。 - Harlin
3
我指出这里有一个语义差异。此时,易读性变得次要。 - Mad Physicist
1
我认为这是公平的。 - Harlin
1
作为 Python 的新手,易读性对我来说非常重要。当然,前提是代码首先按预期工作:P。 - sir_chocolate_soup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接