2024-03-29 06:10:45 发布
网友
这是我试图用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有一些不了解的地方。它是什么?你知道吗
这是因为首先计算r.h.s,然后在值解包期间,为l.h.s__setitem__上的每一项逐个调用。这意味着当计算l.h.sarr[arr.index(...)]时,第一个赋值arr[i] = arr[arr.index(...)]已经发生,因此修改了数组。因此,l.h.s.arr.index(...)不一定返回与r.h.s对应的值相同的值。你知道吗
__setitem__
arr[arr.index(...)]
arr[i] = arr[arr.index(...)]
arr.index(...)
我们可以通过以下代码片段将其可视化:
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)
同时检查docs about evaluation order of expressions。你知道吗
对于您的特定示例,使用最小值的索引,这将导致不操作。以下是按顺序发生的步骤:
arr.index(min(arr[i:]))
m
arr[m]
a
arr[i:]
arr[j]
b
arr.__setitem__(i, a)
i
arr.__setitem__(arr.index(min(arr[i:])), b)
arr[i]
相反,您可以提前计算索引:
index = arr.index(min(arr[i:])) a[i], a[index] = a[index], a[i]
这是因为首先计算r.h.s,然后在值解包期间,为l.h.s
__setitem__
上的每一项逐个调用。这意味着当计算l.h.sarr[arr.index(...)]
时,第一个赋值arr[i] = arr[arr.index(...)]
已经发生,因此修改了数组。因此,l.h.s.arr.index(...)
不一定返回与r.h.s对应的值相同的值。你知道吗我们可以通过以下代码片段将其可视化:
输出:
同时检查docs about evaluation order of expressions。你知道吗
具体示例的更详细分解
对于您的特定示例,使用最小值的索引,这将导致不操作。以下是按顺序发生的步骤:
arr.index(min(arr[i:]))
进行求值(我们称之为m
),然后对arr[m]
进行求值(我们称之为a
;这是arr[i:]
的最小元素)。你知道吗arr[j]
被计算(我们称之为b
)。你知道吗arr.__setitem__(i, a)
,将索引i
处的元素设置为最小值(a
)。你知道吗arr.__setitem__(arr.index(min(arr[i:])), b)
。由于前面的操作(3.)arr.index(min(arr[i:]))
现在将是i
。因此,索引i
处的元素被设置为b
,这是前一个arr[i]
,也就是说,它被设置回其前一个值,从而导致no-op相反,您可以提前计算索引:
相关问题 更多 >
编程相关推荐