

※初めて質問をさせていただきますので、至らない点があればどうか温かく受け入れていただけると幸いです。

以下のように2つの関数 `min_index`, `selectionsort` を作成しました。

[code]

    j = min_index(A[i:])
        A[i],A[i+j] = A[i+j],A[i]
    
[/code]

の部分に関してこのようにすると、思う通りの処理が実行されますが、

[code]

    A[i],A[i + min_index(A[i:])] = A[i + min_index(A[i:])],A[i]
    
[/code]

とすると、swapが行われず困惑しています。

Pythonに関する知識がまだ浅く、エラーコードも出力されないことで行き詰まっている状態です。どなたかご教示いただけますと幸いです。

* * *
[code]

    def min_index(A):
        index = 0
        m = A[0]
    for i in range(1,len(A)):
        if A[i] < m:
            m = A[i]
            index = i
    return index
    
    def selectionsort(A,N):
        for i in range(N):
            j = min_index(A[i:])
            A[i],A[i+j] = A[i+j],A[i]
            #A[i],A[i + min_index(A[i:])] = A[i + min_index(A[i:])],A[i]
    return A
    
[/code]


CC BY-SA 4.0
2020-05-31T16:42:59.853
67169
2020-05-31T23:16:25.170
2020-05-31T17:11:39.173
40421
40421
question
python sort
pythonにおける関数、swapについての質問


まず大前提として、現在ご質問中にあるコードのインデントはPython的に意味のないものなので、以下のように読み直しています。

[code]

    def min_index(A):
        index = 0
        m = A[0]
        for i in range(1,len(A)):
            if A[i] < m:
                m = A[i]
                index = i
        return index
    
    def selectionsort(A,N):
        for i in range(N):
            j = min_index(A[i:])
            A[i],A[i+j] = A[i+j],A[i]
            #A[i],A[i + min_index(A[i:])] = A[i + min_index(A[i:])],A[i]
        return A
    
[/code]

* * *

「swapが行われず」と言うよりも、「代入先の計算が詳細な実行順序に依存するので期待通りの結果になっていない」と思った方がいいでしょう。(結果として「swap」になってないので、まぁ、同じことではあるんですが。)

Pythonの評価順序の基本は、

  * 左→右
  * 代入文の場合は、`=`の右辺→`=`の左辺

と言う順序になります。

今考えているswap型の代入文の場合には、以下のようにドキュメント中に記載されています。

### [6.16. Evaluation
order](https://docs.python.org/3/reference/expressions.html#evaluation-order)

>
[code]

>     expr3, expr4 = expr1, expr2
>  
[/code]

(後ろについている`1`,`2`,...が評価順です。)

式の評価順を示す項目なんで、代入文の代入処理の詳細な順序までは記載されていないんですが、[7.2. Assignment
statements](https://docs.python.org/3/reference/simple_stmts.html#assignment-
statements)の説明と併せて考えると、左辺の`expr3`,
`expr4`のそれぞれの評価の直後に(もしくはそれぞれの評価の一環として)代入処理が行われることになります。

順を追って詳細を見ていくと、以下のような感じになります。言葉での説明だけではわかりにくくなるので、`A = [3, 2, 1]`、`i =
0`とした場合の状態例を付記しておきます。

[code]

    [1] A[i + min_index(A[i:])]を計算              3 2 1 → 3 2 1 i + min_index(A[i:])が2になるので、結果は1
    [2] A[i]を計算                                 3 2 1 → 3 2 1 結果は3
    [3] 上の[1]の結果をA[i]に代入                    3 2 1 → 1 2 1
    [4] 上の[2]の結果をA[i + min_index(A[i:])]に代入 1 2 1 → 3 2 1 この時点では、i + min_index(A[i:])は0になる
    
[/code]

と言うわけで、結局swap処理にはならないわけです。

* * *

このような勘違いを防ぐためには、「Pythonの仕様を隅々まで完全に理解すべき」と言うよりは、「実行順序の詳細で結果が変わってしまうような書き方をしない」と言うのが大切でしょう。

また`min_index`は配列(スライス)の長さに比例して時間のかかる処理なので、そのような処理を何度も繰り返して記載するのも、処理時間上不利になります。

コードインされている側のような書き方をするよう、普段から気をつけた方が良いでしょう。


CC BY-SA 4.0
2020-05-31T23:16:25.170
67170
2020-05-31T23:16:25.170
13972
67169
answer