【问题标题】:Swapping list elements in python where the expressions contain function calls在python中交换表达式包含函数调用的列表元素
【发布时间】:2019-01-23 18:58:16
【问题描述】:

如果arr = [4,3,2,1] 并且我想用数组的最小值交换第一个值,如果我在 python 上使用它

arr[0] , arr[arr.index(min(arr))] = min(arr) , arr[0] 
#or   
arr[0] , arr[arr.index(min(arr))] = arr[arr.index(min(arr))] , arr[0]

他们不工作,但如果我这样做

b = arr.index(min(arr))  
#and then  
arr[0] , arr[b] = arr[b] , arr[0]

这很好用。谁能解释一下为什么?

【问题讨论】:

  • @smci:除了这里实际上不是从左到右。它本来可以设计成从左到右的,但事实并非如此。 (我真的希望 Python 多重赋值被设计为从左到右评估所有表达式,然后开始赋值。)
  • @user2357112:那么请解释一下它是什么。它从左到右解析,然后动态评估每个表达式,是吗?对于元组赋值L1, L2 = R1, R2,首先计算 L1,然后是 R1,然后是 L2,然后是 R2?
  • @smci:不。 R1,R2,L1,(第一次赋值在这里),L2,(第二次赋值在这里)。
  • @smci:较早的答案提到了作业的例外情况,但很容易错过。我已经对其进行了编辑,使其更加清晰。

标签: python arrays python-3.x list operator-precedence


【解决方案1】:

这与操作的顺序有关。

我们可以对列表进行子类化来检测它们以显示它们在做什么。

class TracingList(list):
    def __getitem__(self, key):
        value = super().__getitem__(key)
        print(self, "reading", key, "=", value)
        return value

    def __setitem__(self, key, value):
        print(self, "writing", key, "=", value)
        super().__setitem__(key, value)

    def index(self, value):
        index = super().index(value)
        print(self, "finding index of", value, "=", index)
        return index


arr = TracingList([4, 3, 2, 1])
arr[0], arr[arr.index(min(arr))] = min(arr), arr[0]
print(arr)
print("===")

arr = TracingList([4, 3, 2, 1])
arr[0], arr[arr.index(min(arr))] = arr[arr.index(min(arr))], arr[0]
print(arr)
print("===")

arr = TracingList([4, 3, 2, 1])
b = arr.index(min(arr))
arr[0], arr[b] = arr[b], arr[0]
print(arr)

打印出来

[4, 3, 2, 1] reading 0 = 4
[4, 3, 2, 1] writing 0 = 1
[1, 3, 2, 1] finding index of 1 = 0
[1, 3, 2, 1] writing 0 = 4
[4, 3, 2, 1]
===
[4, 3, 2, 1] finding index of 1 = 3
[4, 3, 2, 1] reading 3 = 1
[4, 3, 2, 1] reading 0 = 4
[4, 3, 2, 1] writing 0 = 1
[1, 3, 2, 1] finding index of 1 = 0
[1, 3, 2, 1] writing 0 = 4
[4, 3, 2, 1]
===
[4, 3, 2, 1] finding index of 1 = 3
[4, 3, 2, 1] reading 3 = 1
[4, 3, 2, 1] reading 0 = 4
[4, 3, 2, 1] writing 0 = 1
[1, 3, 2, 1] writing 3 = 4
[1, 3, 2, 4]

【讨论】:

  • 解释一下,arr[0]arr[arr.index(min(arr))] 被评估和设置之前被设置。因此,一旦arr[0] 设置为 1,min 的索引就变为 0。所以arr[arr.index(min(arr))] 将 4 分配给索引 0。
  • 这意味着如果你改变分配的顺序,即arr = [4,3,2,1]; arr[arr.index(min(arr))], arr[0] = arr[0], min(arr); print(arr),你会得到“正确”的结果。 :o
  • 好的,但是没有解释实际的评估顺序是什么,或者为什么会这样,或者遵循什么原则。这就像说“顺序就是它是什么,因为它就是这样”Python evaluates expressions L-to-R, except for assignments, where the RHS is evaluated before the LHS
猜你喜欢
  • 2017-10-23
  • 1970-01-01
  • 1970-01-01
  • 2017-11-07
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
  • 1970-01-01
  • 2015-04-09
相关资源
最近更新 更多