Pythonic交换两个列表元素
我发现我在Python中需要进行交换操作,于是我写了这样的代码:
arr[first], arr[second] = arr[second], arr[first]
我觉得这样写不是很符合Python的风格。有没有人知道在Python中更优雅的交换方法?
编辑: 我想再举个例子来说明我的疑问:
self.memberlist[someindexA], self.memberlist[someindexB] = self.memberlist[someindexB], self.memberlist[someindexA]
这就是Python中唯一的交换方法吗?
5 个回答
1
a, b = b, a
这个写法是非常简洁的,除了变量名外,它只有三个字符。可以说这是非常符合Python风格的写法。
另一种方法是使用一个临时变量:
self.memberlist[someindexA], self.memberlist[someindexB] = self.memberlist[someindexB], self.memberlist[someindexA]
..变成..
temp = self.memberlist[someindexB]
self.memberlist[someindexB] = self.memberlist[someindexA]
self.memberlist[someindexA] = temp
我觉得这种写法比较复杂,不够“直观”。
还有一种方法,可能在变量名比较长的时候更容易阅读:
a, b = self.memberlist[someindexA], self.memberlist[someindexB]
self.memberlist[someindexA], self.memberlist[someindexB] = b, a
16
a, b = b, a
这是一个非常符合Python风格的写法。 它简短且易于阅读,只要你的变量名足够短就可以了。
14
在你的示例代码中,有一点我可能会建议修改:如果你要多次使用像 self.memberlist
这样很长的名字,通常先把它简化成一个短一点的名字会更容易阅读。比如说,避免使用这个又长又难读的:
self.memberlist[someindexA], self.memberlist[someindexB] = self.memberlist[someindexB], self.memberlist[someindexA]
你可以这样写:
L = self.memberlist
L[someindexA], L[someindexB] = L[someindexB], L[someindexA]
记住,Python 是通过引用来工作的,所以 L 实际上指向的就是和 self.memberlist
一模一样的对象,而不是它的一个副本(同样的道理,赋值的速度非常快,无论列表有多长,因为它并没有被复制,只是多了一个引用)。
我觉得没有必要再复杂化,当然也可以想出一些花哨的用法,比如对于正常的索引 >=0
:
def slicer(a, b):
return slice(a, b+cmp(b,a), b-a), slice(b, a+cmp(a,b), a-b)
back, forth = slicer(someindexA, someindexB)
self.memberlist[back] = self.memberlist[forth]
我认为搞清楚这些“高级”用法是个不错的想法,既是有趣的思维练习,也很有趣——我建议感兴趣的读者,在理解了基本概念后,关注一下 +cmp
的作用,以及它们是如何处理三种情况的(a>b, a<b, a==b)[[不过不适用于负索引,为什么呢?要怎么修改切片器才能解决这个问题?]]。但是在实际代码中使用这种复杂的方法通常是多余的,反而会让事情变得更加混乱,维护起来也比简单直接的方法要困难。
记住,简单比复杂更好!