Python简单交换功能

Rhs*_*Rhs 12 python swap

我在尝试学习python时遇到了这个问题.考虑以下功能:

def swap0(s1, s2):
    assert type(s1) == list and type(s2) == list
    tmp = s1[:]
    s1 = s2[:]
    s2 = tmp
return

s1 = [1]
s2 = [2]
swap0(s1, s2)
print s1, s2
Run Code Online (Sandbox Code Playgroud)

s1和s2会打印什么?

运行问题后,我发现print语句将打印1 2.似乎s1和s2的值没有从swap0函数中改变.我能想到的唯一解释是因为这条线.

tmp = s1[:]
Run Code Online (Sandbox Code Playgroud)

由于s1 [:]是一个副本,因此在函数调用中s1的值不会改变是有道理的.但是因为参数swap0是(s1,s2),我不确定是否在执行tmp = s1 [:]之后.我随时都可以

s1 = something...
Run Code Online (Sandbox Code Playgroud)

它将是对s1副本的引用,而不是s1本身.有人可以提供更好的解释吗?谢谢.

Tho*_*mas 25

这是因为它赋予新值s1s2内部swap0功能.这些赋值不会在函数外传播.如果你只是在函数调用的位置复制并粘贴函数体,你会发现它是有效的.

您可以通过修改参数引用的对象而不是参数本身来解决此问题:

def swap0(s1, s2):
    assert type(s1) == list and type(s2) == list
    tmp = s1[:]
    s1[:] = s2
    s2[:] = tmp
Run Code Online (Sandbox Code Playgroud)

但是,在Python中进行交换的更简单,更好的方法就是:

s1, s2 = s2, s1
Run Code Online (Sandbox Code Playgroud)

这也只会将这些特定引用交换到列表,而不是列表内容本身.

  • 注意,如果你对列表中的`s1`和/或`s2`有其他引用,那么`swap0`和`s1,s2 = s2,s1`会有什么显着的区别. (4认同)

ins*_*get 11

正因为如此,你最后print会打印出的原始值s1s2.这是因为您只是在函数范围内交换它们.这样做不会影响它们在函数外部的值(即在调用函数后它们的值之后)

如果它们是可变类型(list,set,dict等),那么你可以就地内对其进行修改swap.但是,这限制swap了仅适用于可变类型.

因此,您最好以相反的顺序返回输入:

def swap(s1, s2):
    return s2, s1

s1 = 'a'
s2 = 'b'
s1, s2 = swap(s1, s2)
print s1, s2 # prints 'b a'
Run Code Online (Sandbox Code Playgroud)

当然,您可以在一行中执行以下操作:

s1, s2 = s2, s1
Run Code Online (Sandbox Code Playgroud)

干杯!

  • 好点子!我没有想到这一点。`s1, s2 = copy.deepcopy(s2), copy.deepcopy(s1)` 会解决这个问题吗? (2认同)

Zer*_*eus 6

其他答案解释了什么是错的.这是一个做你想要的版本:

def swap(s1, s2):
    assert isinstance(s1, list) and isinstance(s2, list)
    s1[:], s2[:] = s2[:], s1[:]
Run Code Online (Sandbox Code Playgroud)

另请参见:isinstance与type