尝试学习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
什么将S1和S2的打印?
运行问题后,我发现,打印语句将打印1 2似乎的S1和S2的价值并没有从改变swap0
功能。 我能想到的唯一解释是,因为该行的。
tmp = s1[:]
由于S1 [:]是一个副本,这是有道理的,S1的值不会在函数调用改变。 然而,由于参数swap0
是(S1,S2),我不是,如果这样做TMP = S1后,确认[:]。 每当我做
s1 = something...
这将是S1的副本的引用,而不是S1本身。 有人可以提供一个更好的解释? 谢谢。
这是因为它赋予新的价值,以s1
和s2
内部swap0
功能。 这些任务并不功能外传播。 你会看到它,如果你只是在函数调用的地方复制和粘贴函数体工作。
您可以解决此通过修改参数引用,而不是参数本身的对象:
def swap0(s1, s2):
assert type(s1) == list and type(s2) == list
tmp = s1[:]
s1[:] = s2
s2[:] = tmp
然而,更容易,更好的办法做到在Python交换很简单:
s1, s2 = s2, s1
这也只会掉那些特别引用的名单,但不在名单内容本身。
正因为如此,您的最终print
将打印出的原始值s1
和s2
。 这是因为你只函数的范围内交换他们。 这样做会不会影响功能以外的值(函数被调用后,它们的值之后,IE)
如果它们是可变类型( 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'
当然,你可以如下做到这一切在一行:
s1, s2 = s2, s1
干杯!
其他答案解释发生了什么错误。 这里有你想要做什么的一个版本:
def swap(s1, s2):
assert isinstance(s1, list) and isinstance(s2, list)
s1[:], s2[:] = s2[:], s1[:]
另请参见: isinstance与类型
您也可以做到这一点通过使用索引和循环旧swaping方法如果两个列表具有相同的长度。 这是一种古老的学校,但将在了解索引帮助
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
b = [0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
for i in range(0, len(a)):
a[i] = a[i] + b[i]
b[i] = a[i] - b[i]
a[i] = a[i] - b[i]
print(a)
print(b)
这会给输出为:
[0,9,8,7,6,5,4,3,2,1]
[1,2,3,4,5,6,7,8,9,0]
或者也可以使用异或来完成。 XOR运算符是按位操作,其执行的操作数例如之间的异或运算。
a = 5 #0b101
b = 4 #0b100
c = a ^ b #0b001
这里0b101
是5的二进制表示和0b100
为4的二进制表示,当你XOR这些你会在输出中作为0b001
即1。 XOR返回1分输出的结果,如果一个,且只有一个的输入是1,如果两个输入均为0或都是1,0输出的结果。 我们可以交换使用异或为如两个变量:
a = 5 # 0b0101
b = 9 # 0b1001
a = a ^ b # Xor (0b0101, 0b1001) = 0b1100 (12)
b = a ^ b # Xor (0b1100, 0b1001) = 0b0101 (5)
a = a ^ b # Xor (0b1100, 0b0101) = 0b1001 (9)
print("a = {} and b = {}".format(a, b))
输出将是a = 9 and b = 5
同样,我们也可以通过一些有意思的东西做异或操作如交换两个列表:
a = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 ]
b = [ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
for i in range(0, len(a)) :
a[i] = a[i] ^ b[i]
b[i] = a[i] ^ b[i]
a[i] = a[i] ^ b[i]
print(a)
print(b)
输出:
[0, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
让我们另一种情况下,如果我们需要交换列表中的物品如什么:我们有一个列表这样的x = [ 13, 3, 7, 5, 11, 1 ]
,我们需要交换的物品像这样x = [ 1, 3, 5, 7 , 11, 13 ]
因此,我们可以通过使用两个位运算符执行此异或^
和称赞~
代码:
# List of items
a = [ 13, 3, 7, 5, 11, 1 ]
# Calculated the length of list using len() and
# then calulated the middle index of that list a
half = len(a) // 2
# Loop from 0 to middle index
for i in range(0, half) :
# This is to prevent index 1 and index 4 values to get swap
# because they are in their right place.
if (i+1) % 2 is not 0 :
#Here ~i means the compliment of i and ^ is Xor,
# if i = 0 then ~i will be -1
# As we know -ve values index the list from right to left
# so a [-1] = 1
a[i] = a[i] ^ a[~i]
a[~i] = a[i] ^ a[~i]
a[i] = a[i] ^ a[~i]
print(a)
所以输出将是[1, 3, 5, 7, 11, 13]
哟可以有这样的:
def swap(x , y):
x , y = y , x
return x , y
x = 5
y = 10
print ('x is {0} and y is {1}'.format(x,y)) # x is 5 and y is 10
x , y = swap(x,y) # doing swap
print ('x is {0} and y is {1}'.format(x,y)) # x is 10 and y is 5
有没有必要功能都没有。 A,B = B,A是卓有成效的。
>>> a,b=1,2
>>> print (a,b)
(1, 2)
>>> a,b=b,a
>>> print (a,b)
(2, 1)
>>>
它适用于阵列为好。 但如果你因此在这里想要的功能它是
def swap(a,b)
return b,a