我正在学习python,我怎么知道一个命令或方法是&{39; in place algorithm' ?
尝试'大'使用命令输入并检查运行时是否足够好?
例如,假设我有一个包含100,000个元素的列表lst
。
我查看了以下两个命令,并且两个命令都已完成了'在片刻:lst = lst[ : :-1]
和lst.reverse()
。那么这是否意味着两者都到位了?
答案 0 :(得分:3)
如果某个函数就位,那么它将修改调用它的对象。如果没有,那么它将返回结果。
sorted(lst) # returns the sorted form of lst
lst.sort() # sorts lst
这就是它的全部。不要试图将其与运行时间或效率联系起来。
答案 1 :(得分:3)
就地操作通常在Python中返回None
,因此在您的情况下lst.reverse()
是一个就地操作,因为它返回None
并修改列表。虽然lst[::-1]
会返回您重新分配给lst
的新列表。
>>> lst = range(1000)
>>> id(lst)
154457996
>>> lst = lst[::-1]
>>> id(lst) #id changed.
160699852
>>> lst = range(1000)
>>> id(lst)
160699340
>>> lst.reverse()
>>> id(lst) #same id
160699340
答案 2 :(得分:2)
要回答这个问题,我们必须先知道什么是适当的算法'?
通过维基百科,an in-place algorithm是一种算法,它使用具有常量量额外存储空间的数据结构来转换输入。
'覆盖输入'之间的关系是什么?和'就地算法':
不,例如,快速排序总是覆盖它的输入,但它需要O(log(n))额外空间来跟踪递归函数调用。
不,例如,在数组中找到最小数字的算法,它是一个就地算法,只需要O(1)额外空间,但不需要覆盖它的输入。
因此,它们之间没有绝对的关系,输入通常被原位算法覆盖。
好吧,我认为你必须看看它的实现,源代码,同样的方法可能会使用不同的算法,毕竟方法或函数与算法不一样。
顺便说一句,有一种简单的方法可以知道方法的输入是否被覆盖:
>>> lst = [1, 2, 3]
>>> id(lst)`
3070142764
>>> lst = lst[: : -1]
>>> id(lst)
3070142828
>>> lst.reverse()
>>> id(lst)
3070142828
在lst[: : -1]
之后,lst的ID已更改,因此lst[: : -1]
创建了一个新的列表对象,在lst.reverse()
之后,lst的ID未被更改,因此{ {1}}覆盖了它的输入。
答案 3 :(得分:1)
如果你正在使用像iPython这样的东西,你可以问翻译 -
In [1]: x = [1, 2, 3]
In [2]: ? x.reverse
Type: builtin_function_or_method
Base Class: <type 'builtin_function_or_method'>
String Form:<built-in method reverse of list object at 0x0362EB48>
Namespace: Interactive
Docstring: L.reverse() -- reverse *IN PLACE*
因此reverse
方法就位。一般来说,像
In [3]: x = x[::-1]
由于首先创建了副本,然后将其分配给x
,因此不会就位。你知道,由于类似的任务
,这不可能就位In [4]: y = x[::-1]
当然必须创建x
的其他副本。
答案 4 :(得分:0)
在我的头脑中,我认为在运行程序时查看内存消耗将是一个更好的指标。据我所知&#34;就地&#34;,这意味着运行算法不需要(或很少)额外的空间。 http://en.wikipedia.org/wiki/In-place_algorithm
对于您的特定示例,我认为快速运行时间很可能是由于使用了列表实现。我的第一个猜测是列表是使用双链表实现的。这反过来当然意味着反向将在原地进行。
如果你想确定,我认为你需要首先进入实现相关算法的代码。