【问题标题】:Python swap method not workingPython交换方法不起作用
【发布时间】:2017-07-03 07:03:24
【问题描述】:

我正在尝试为 python 制作一个冒泡排序方法,仅用于便便和咧嘴笑。我认为我的交换方法不起作用。

def bubbleSort(list):
length = len(list)
for i in range(length - 1):
    if list[i] > list[i+1]:
        #swap
        swap(list[i], list[i+1])
        print(list)
print(list)

def swap(s1, s2):
    # assert type(s1) == list and type(s2) == list
    # tmp = s1[:]
    # s1[:] = s2
    # s2[:] = tmp
    s2, s1 = s1, s2

程序吐出我的列表,但没有任何变化告诉我我的交换方法不起作用。

【问题讨论】:

  • 当你做s2, s1 = s1, s2时,只交换swap函数中的局部变量名。由于许多 python 类型是不可变的,你不能编写一个简单的交换函数。
  • 这是 Python 不支持传递引用语义的一个很好的例子。如果是这样,您可以使用相同的主体编写一个交换函数并产生您想要的结果!

标签: python sorting swap


【解决方案1】:

如果将整数、字符串或元组等不可变参数传递给函数,则传递的行为类似于按值调用。对象引用被传递给函数参数。它们不能在函数内更改,因为它们根本无法更改,即它们是不可变的。如果我们传递可变参数,情况就不同了。它们也通过对象引用传递,但可以在函数中就地更改。如果我们将一个列表传递给一个函数,我们必须考虑两种情况: 列表的元素可以就地更改,即即使在调用者的范围内,列表也会被更改。如果为名称分配了新列表,则旧列表不会受到影响,即调用者范围内的列表将保持不变。

严格来说,在您将列表元素传递给swap 函数的示例中,不会有效果。虽然有 python 语法允许你直接写这个:

list[i], list[i+1] = list[i+1], list[i]

不确定将如此微小的逻辑提取到单独的函数中的目的是什么。

PS。要阅读有关评估策略的更多信息,例如call-by-value、call-by-reference 以及为什么不同,你可以看看wiki

PPS。正如评论中正确指出的那样,python 的常见评估策略是“Call-by-Sharing”,例如:

共享调用(也称为对象调用或对象共享调用)是一种评估策略,最早由 Barbara Liskov 等人提出。 1974 年用于 CLU 语言。 [5]它被 Python、[6] Iota、[7] Java(用于对象引用)、Ruby、JavaScript、Scheme、OCaml、AppleScript 等语言使用。但是,“共享呼叫”一词并不常用。不同来源的术语不一致。例如,在 Java 社区中,他们说 Java 是按值调用的。 [8]共享调用意味着语言中的值基于对象而不是原始类型,即所有值都是“装箱”的。

【讨论】:

  • 请注意,Python 评估策略的技术名称(虽然不常用)是call by sharing。它与 Java、Javascript、Ruby 和许多其他人共享。
  • 我知道它是“Call-by-Object”,而您的观察仍然正确。
猜你喜欢
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
  • 2010-11-28
  • 2018-06-25
  • 2011-01-03
相关资源
最近更新 更多