为什么 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.
据我了解,您可以通过比较修改列表(可变)返回的差异来快速看到区别,即使用 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
?与对象方法不同,函数无法知道。
正在解决一个算法问题,必须反转列表。 完成后,这就是我的代码的样子:
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.
据我了解,您可以通过比较修改列表(可变)返回的差异来快速看到区别,即使用 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
?与对象方法不同,函数无法知道。