如何避免Python中的对象别名?
我正在尝试写一个函数,用来检查一个列表是否是排好序的(返回 True
或 False
)。我该怎么做才能避免多个变量指向同一个东西呢?
def is_sorted(t):
a = t
a.sort()
当我这样做的时候,它会把 a
和 t
都排序了。我该怎么避免这种情况呢?
7 个回答
3
你可以通过创建一个列表的副本来做到这一点,像这样:
def is_sorted(t):
a = t[:] # create a copy
a.sort()
6
编辑: 请查看 这个回答,了解正确的做法。我会把我的回答留在这里以供后人参考(处理这种情况的正确方法是什么?),但这不应该被视为问题的最佳答案,即使它是一个正确的答案。
针对你的具体问题,你可以使用 copy.copy
(或者用切片语法 [:]
)来创建原始列表的一个副本:
import copy
def is_sorted(t):
a = copy.copy(t) # could also do: a = t[:]
a.sort()
return a == t
不过,更好的方法是使用 sorted
函数来返回一个排序后的列表副本:
def is_sorted(t):
return sorted(t) == t
或者: is_sorted = lambda t: sorted(t) == t
9
这里有一种O(n)的做法
>>> from itertools import islice, izip
>>> def is_sorted(L):
... return all(i<=j for i,j in izip(L, islice(L,1,None)))
...
>>> is_sorted(range(50))
True
>>> is_sorted(range(50)+[20])
False
它会短路,所以如果列表在一开始就没有排序的话,速度会非常快
下面是一个简单的程序,用来比较一些其他的选择
import random
import time
from itertools import islice, izip
def is_sorted1(L): # 0.0006s
return all(i<=j for i,j in izip(L, islice(L,1,None)))
def is_sorted2(L): # 0.117s
return all(L[i] < L[i+1] for i in range(len(L)-1) )
def is_sorted3(L): # 2.344s
return L == sorted(L)
def is_sorted4(L): # 0.0002s
return all(L[i] < L[i+1] for i in xrange(len(L)-1) )
A = [range(random.randrange(100000)) for i in range(100)]
for a in A:
random.shuffle(a)
for f in is_sorted1, is_sorted2, is_sorted3, is_sorted4:
s=time.time()
for a in A:
f(a)
print time.time() - s