为什么 Python return None 在 list.reverse() 上?

Why does Python return None on list.reverse()?

正在解决一个算法问题,必须反转列表。 完成后,这就是我的代码的样子:

def construct_path_using_dict(previous_nodes, end_node):
    constructed_path = []
    current_node = end_node
    while current_node:
        constructed_path.append(current_node)
        current_node = previous_nodes[current_node]
    constructed_path = reverse(constructed_path)    
    return constructed_path

但是,在此过程中,我尝试了 return constructed_path.reverse(),但我意识到它并不是 return 列表... 为什么会这样?
我应该能够直接 return 反向列表,而无需先执行 list.reverse()list = reverse(list) ,这难道不合理吗?

list.reverse 原地反转,修改调用它的列表。通常,就地操作的 Python 方法不会 return 它们操作的对象,以避免混淆 returned 值是否是副本。

您可以反转 return 原始列表:

constructed_path.reverse()
return constructed_path

或return原始列表的反向迭代器,它不是列表但不涉及创建与第一个列表一样大的第二个列表:

return reversed(constructed_path)

或return一个新列表,包含原始列表的反向元素:

return constructed_path[::-1]
# equivalent: return list(reversed(constructed_path))

如果您不关心性能,只需选择您认为最易读的选项即可。

methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. 1 This is a design principle for all mutable data structures in Python.

PyDocs 5.1

据我了解,您可以通过比较修改列表(可变)返回的差异来快速看到区别,即使用 list.reverse() 并改变作为元组中的元素的列表(非-可变),同时调用

id(list)

id(tuple_with_list)

突变前后。返回 none 的可变数据类型突变​​部分允许它们成为 changed/expanded/pointed-to-by-multiple 引用而无需重新分配内存。

我要写的东西已经在这里说了,但我还是会写,因为我认为它可能会增加一些清晰度。

您在问为什么 reverse 方法不 return 一个(对)结果的引用,而是就地修改列表。在official python tutorial中,它是这样说的:

You might have noticed that methods like insert, remove or sort that only modify the list have no return value printed – they return the default None. This is a design principle for all mutable data structures in Python.

换句话说(或者至少,我是这么想的)- python 尝试尽可能就地改变(即,在处理不可变数据结构时) ,并且当它就地发生变异时,它不会 return 对列表的引用 - 因为那样看起来它是 returning a 列表,当它真的是return旧列表时。

需要明确的是,这仅适用于对象 方法 ,不适用于采用列表的函数,例如,因为函数无法知道它是否可以改变传入的可迭代对象。你传递的是 list 还是 tuple?与对象方法不同,函数无法知道。