15

Pythonでスワップを実行する必要があることがわかり、このようなものを書きました。

arr[first], arr[second] = arr[second], arr[first]

これはそれほどpythonicではないと思います。誰かがよりエレガントなPythonでスワップを行う方法を知っていますか?

編集: 別の例が私の疑問を示すと思います

self.memberlist[someindexA], self.memberlist[someindexB] = self.memberlist[someindexB], self.memberlist[someindexA]

これは、python でスワップするための唯一の利用可能なソリューションですか? いろいろ調べたのですが、いい答えが見つかりませんでした...

4

5 に答える 5

16
a, b = b, a

完全に Pythonic のイディオムです。変数名が十分に短い限り、短くて読みやすいです。

于 2009-07-19T12:31:08.150 に答える
14

サンプルコードで変更する可能性があることの1つは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(同様に、リストがどれだけ長くても割り当ては非常に高速です。とにかくコピーされないためです。それはただ 1 つです。もっと参考に)。

これ以上複雑にする必要はないと思いますが、もちろん (a, b の "通常の" インデックスの場合>=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がどのように機能するかに焦点を当てることをお勧めします。 3 つの可能性 (a>b、a<b、a==b) [[負のインデックスではありませんが、なぜでしょうか? これを修正するには、スライサーをどのように変更する必要がありますか?]]。しかし、本番コードでこのような手の込んだアプローチを使用することは、一般的にやり過ぎであり、まったく不当であり、単純で単純なアプローチよりも保守が難しくなります。

シンプルは複雑よりも優れていることを忘れないでください。

于 2009-07-19T16:36:43.047 に答える
1

a, b = b, aあなたが得られるのと同じくらい短く、それはたった3文字です(変数名は別として).あなたが得るのと同じくらいPythonらしいです.

1 つの代替手段は、通常の use-a-temp-variable です。

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
于 2009-07-19T13:17:42.400 に答える
1

よりエレガントにする方法を想像するのは難しいです: 架空の組み込み関数を使用して ...swap_sequence_elements(arr, first, second)エレガント? たぶん、しかしこれは YAGGI の領域です -- あなたはそれを理解するつもりはありません ;-) -- そして関数呼び出しのオーバーヘッドはあなたがそれを自分で実装することを先延ばしにする/はずです。

あなたが持っているものは、代替のインライン方法よりもはるかにエレガントです:

temp = arr[first]
arr[first] = arr[second]
arr[second] = temp

そして(ボーナス!)も高速です(バイトコードが a plus aROT_TWOよりも高速であるという不合理ではない仮定に基づいて)。LOAD_FASTSTORE_FAST

于 2009-07-19T13:05:52.747 に答える
-1

スライス表記のステップ引数を利用して、次のようなことができると思います。

myarr[:2] = myarr[:2][::-1]

これがより明確であるか、よりpythonicであるかはわかりませんが...

于 2009-07-20T06:01:25.463 に答える