Python成语返回第一项或无?
最 Pythonic 的方法是最受好评的答案所展示的,当我阅读这个问题时,这是我首先想到的。下面是如何使用它,首先如果可能为空的列表被传递给一个函数:
def get_first(l):
return l[0] if l else None
如果列表是从get_list
函数返回的:
l = get_list()
return l[0] if l else None
Python 3.8 中的新功能,赋值表达式
赋值表达式使用就地赋值运算符(非正式地称为海象运算符),:=
Python 3.8 中的新功能,允许我们就地进行检查和赋值,允许单行:
return l[0] if (l := get_list()) else None
作为一个长期使用 Python 的用户,这感觉就像我们试图在一行上做太多事情 - 我觉得做假定性能相同的样式会更好:
if l := get_list():
return l[0]
return None
支持这一表述的是 Tim Peter在 PEP 中提议对语言进行这种更改的文章。他没有提到第一个公式,但基于他喜欢的其他公式,我认为他不会介意。
此处演示的其他方法,并附有解释
for
当我开始尝试想出聪明的方法来做到这一点时,这是我想到的第二件事:
for item in get_list():
return item
这假定函数在这里结束,隐式返回None
ifget_list
返回一个空列表。下面的显式代码是完全等价的:
for item in get_list():
return item
return None
if some_list
还提出了以下内容(我更正了不正确的变量名称),它也使用了隐式None
. 这将比上述更可取,因为它使用逻辑检查而不是可能不会发生的迭代。这应该更容易立即理解正在发生的事情。但是如果我们是为了可读性和可维护性而编写的,我们还应该return None
在末尾添加显式:
some_list = get_list()
if some_list:
return some_list[0]
切片or [None]
并选择第零个索引
这也是投票率最高的答案:
return (get_list()[:1] or [None])[0]
切片是不必要的,它会在内存中创建一个额外的单项列表。以下应该更高效。解释一下,or
如果第一个元素False
在布尔上下文中,则返回第二个元素,因此如果get_list
返回一个空列表,则括号中包含的表达式将返回一个带有 'None' 的列表,然后将通过0
索引访问该列表:
return (get_list() or [None])[0]
下一个使用这样一个事实,如果第一项True
在布尔上下文中,则返回第二项,并且由于它引用 my_list 两次,它并不比三元表达式好(技术上不是单行):
my_list = get_list()
return (my_list and my_list[0]) or None
next
然后我们有以下巧妙的使用内建next
和iter
return next(iter(get_list()), None)
解释一下,iter
返回一个带有.next
方法的迭代器。(.__next__
在 Python 3 中。)然后内置next
调用该.next
方法,如果迭代器用尽,则返回我们给出的默认值,None
.
多余的三元表达式 ( a if b else c
) 和回旋
提出了以下建议,但反过来会更好,因为逻辑通常在积极而不是消极中更好地理解。由于get_list
被调用了两次,除非结果以某种方式被记忆,否则这将表现不佳:
return None if not get_list() else get_list()[0]
更好的逆:
return get_list()[0] if get_list() else None
更好的是,使用一个局部变量,这样get_list
它只被调用一次,你首先讨论了推荐的 Pythonic 解决方案:
l = get_list()
return l[0] if l else None