質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.62%

ソートする前とソートしたあとの配列の順序をトレースしたい python

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,202

moto_i

score 20

下記の配列があるとします。

NUM = [7, 5,1,6,9]
NUM[0] = 7, NUM[1] = 5. NUM[2] = 1, NUM[3] = 6, NUM[4]= 9
これをソートすると

NUM = [9,7,6,5,1]
になりますが、大きい順にソートする前の配列番号がどのように
動いたかを確認できるプログラムの書き方を教えてください。

この場合ですと
NUM[4], NUM[0], NUM[3], NUM[1], NUM[2]

という情報が知りたいです。
よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+6

numを直接ソートする代わりにnumの添え字をソートすると並べ替えを一度きりにできます。この方法を使うとsortアルゴリズムが安定ソートでない場合でも安定ソートにできるという応用もききます。(自分はPythonのsortedが安定ソートなのかどうなのかすぐに出てきませんが...)

sorted関数のkey引数はかなり使い出があります(というよりそれを使わないと大したソートができないともいえましょう)。

num = [7, 5, 1, 6, 9]
indices = [*range(len(num))]
sorted_indices = sorted(indices, key=lambda i: -num[i])
sorted_num = [num[i] for i in sorted_indices]
print(sorted_num)      # ==> [9, 7, 6, 5, 1]
print(sorted_indices)  # ==> [4, 0, 3, 1, 2]

sorted関数にせよなんにせよ関数の機能を覚える際にどんな引数があるか(どんなオプション機能があるか)をよく把握しておくことがプログラミングの幅を広げる(要するにできることの引き出しを増やしておく)ためのコツと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/23 14:51

    回答ありがとうございます。
    引き出しが一つ増えました。
    頂いた答えを正確に理解できない部分もありますが。勉強していきたいと思います。

    キャンセル

+3

enumerateで添え字ごとタプルにしてソートする、というのはどうでしょう?

NUM = [7, 5,1,6,9]
list( zip( *reversed( sorted( [ ( x, i ) for i, x in enumerate( NUM ) ] ) ) ) )[1]
#(4, 0, 3, 1, 2)
追記

1位 麺 9個、 2位 魚 7個 3位 米 のような情報がわかるようにしたいのです。 

それなら、こうでしょうか。

A= ("魚","肉","菓子","米","麺")
B= (7,5,1,6,9)
print( *reversed( sorted( zip( B, A ) ) ) )
#(9, '麺') (7, '魚') (6, '米') (5, '肉') (1, '菓子')

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/23 14:48

    回答ありがとうございます。たった一行でここまでできることに驚きです。

    キャンセル

0

私ならオブジェクトの配列を用意する。

Pythonでできるかどうかわからんけど、

実際のデータと "確認用の配列" (リスト?) をひとまとめにしたオブジェクトの配列にしておく。

それを自前でバブルソートやマージソートといった試すべきソートを組んで、

移動させる前に "確認用の配列" に 現在の場所を入れておく。

これを完了するまで行う。

...うん? ちょっと待って。もしかして 元と後のやつの場所比較ってこと?

それなら普通に 二つの配列を用意すればいいだけじゃないの?

オリジナルを num_org[] (すでにデータが入っているとして) として これをコピーして num_sorted[] を定義。

この num_sorted[] のほうをソートする。

で、num_sorted[i] が num_org[] のどこにあるかforとかでチェックする。

っていう風にすればいいんじゃないの?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/23 16:06

    横からすみません。

    Pythonには構造体もインターフェースもありませんです。一応、抽象クラス的なものはあります。
    こういうときは辞書を使うことが多いと思います。

    キャンセル

  • 2019/03/24 00:19

    BeatStarさん、対応ありがとうございました。
    Lhankor_Mhyさんのプログラムでしたいプログラミングができました。

    キャンセル

  • 2019/03/25 10:53

    Lhankor_Mhyさん。

    あー、なるほど。辞書...ですか。
    Pythonにやっぱり構造体はないんですねぇ... ( 一応Javaにも無いことから何となく考えてはいましたが... )

    キャンセル

0

値に重複が無いので有れば、

NUM = [7,5,1,6,9]
NUM1 = sorted(NUM, key=lambda x: -x)
print(NUM1)
print([NUM.index(x) for x in NUM1])


重複があると、最初に見つかった場所の添え字になりますね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/03/23 14:52

    回答ありがとうございます。
    すみません。値が重複することはあります。
    このやりかたも参考にさせて頂きます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る