这是我尝试使用Python编写的基本选择类型。
arr = [64,12,35,312,45,12,50,80,0,4,6,8,92]
for i in range(len(arr)):
arr[i], arr[arr.index(min(arr[i:]))] = arr[arr.index(min(arr[i:]))], arr[i]
但是,swap表达式不起作用。很明显,我不了解Python。什么事?
答案 0 :(得分:2)
这是因为首先计算r.h.s,然后在拆包过程中,对l.h.s x
上的每个项目依次调用。这意味着当计算l.h.s y
时,第一个赋值__setitem__
已经发生,因此修改了数组。因此,l.h.s。 arr[arr.index(...)]
不一定返回与r.h.s对应值相同的值。
我们可以使用以下代码段对其进行可视化:
arr[i] = arr[arr.index(...)]
哪个输出:
arr.index(...)
还要检查docs about evaluation order of expressions。
对于您的特定示例,使用最小值的索引,将导致无操作。这些是按顺序执行的步骤:
class Test:
def __getitem__(self, x):
print(f'get {x}')
return x
def __setitem__(self, x, y):
print(f'set {x}={y}')
class Index:
def __init__(self, x):
self.x = x
print(self)
def __repr__(self):
return f'{type(self).__name__}({self.x})'
test = Test()
test[Index(0)], test[Index(1)] = test[Index(2)], test[Index(3)]
进行评估(将其命名为Index(2)
get Index(2)
Index(3)
get Index(3)
Index(0)
set Index(0)=Index(2)
Index(1)
set Index(1)=Index(3)
),然后对arr.index(min(arr[i:]))
进行评估(将其命名为m
;这是{{ 1}})。arr[m]
被评估(我们将其命名为a
)。arr[i:]
,将索引arr[j]
处的元素设置为最小值(b
)。arr.__setitem__(i, a)
被评估。由于之前的操作(3。),i
现在将变为a
。因此,将索引arr.__setitem__(arr.index(min(arr[i:])), b)
处的元素设置为arr.index(min(arr[i:]))
之前的i
,即将其设置回其先前的值,从而导致无操作。相反,您可以预先计算索引:
i