2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pythonでプライオリティキューで独自のオブジェクトのソートをやってみる

Posted at

##実行環境
python 3.7.3

##やりたいこと
pythonを使ってプライオリティキューを使う。
独自のオブジェクトをソートしたいなど、ちょっと応用したい。

##プライオリティキューとは
優先度付キューとも言う。
使う場面は、要素数が変化しつつ、ソートしたいとき。
もしくは、ソートの状態を保ちつつ、要素をリストに追加したいとき。

他のいろんな人が参考記事とか書いてるので、詳しくは割愛。
(https://qiita.com/ell/items/fe52a9eb9499b7060ed6)

##独自のオブジェクトをソートしたい。
first_name,last_nameの二つの属性を持つNameクラスのオブジェクトをいろんな条件でソートしてみる。

まず、ベースとして以下のクラスを生成する。


class Name(object):
    def __init__(self,first_name,last_name):
        self.first_name = first_name
        self.last_name = last_name
    
    def __lt__(self,other):
        return other.first_name > self.first_name
    
    def __repr__(self):
        return self.first_name + " " + self.last_name

今回の肝となるのは__lt__という特殊メソッド。
自分より相手が小さいとはどういう状況かを設定することができる。
(ほかにもいろんな特殊メソッドがあります。各自調べてみてください
https://blog.codecamp.jp/python-class-code)

実際にheapqを用いてソートしてみる。

from heapq import heapify,heappush,heappop
name1 = Name("james","smith")
name2 = Name("john","johnson")
name3 = Name("robert","williams")
name4 = Name("michael","brown")
name5 = Name("william","jones")
name6 = Name("david","brown")
name7 = Name("james","miller")
name8 = Name("david","davis")

name_list = [name1,name2,name3,name4,name5,name6,name7,name8]
heapify(name_list)
for i in range(len(name_list)):
    print(heappop(name_list))

heapqの使い方は公式ドキュメントに詳しく載っているのでこちらを参照してください。→https://docs.python.org/ja/3/library/heapq.html

実行結果はこちら
david brown
david davis
james miller
james smith
john johnson
michael brown
robert williams
william jones

__lt__メソッドには、ファーストネームだけを基準にして、大小判定するように設定しているので、ちゃんと、ファーストネームが小さい順に並んでいることがわかります。

応用してみる

次に、練習として、ファーストネームでまずソートして、その次にラストネームで逆向きにソートしてみましょう。期待される出力は以下の通りです。

david davis
david brown
james smith
james miller
john johnson
michael brown
robert williams
william jones

ファーストネームは小さい順に並んでいますが、ラストネームは大きい順に並んでいます。これの実装例は下のコードをご覧ください。

class Name(object):
    def __init__(self,first_Name,last_Name):
        self.first_Name = first_Name
        self.last_Name = last_Name
    
    def __lt__(self,other):
        if other.first_Name == self.first_Name:
            return other.last_Name < self.last_Name
        else:
            return other.first_Name > self.first_Name
    
    def __repr__(self):
        return self.first_Name +" "+ self.last_Name


from heapq import heapify,heappush,heappop
name1 = Name("james","smith")
name2 = Name("john","johnson")
name3 = Name("robert","williams")
name4 = Name("michael","brown")
name5 = Name("william","jones")
name6 = Name("david","brown")
name7 = Name("james","miller")
name8 = Name("david","davis")

name_list = [name1,name2,name3,name4,name5,name6,name7,name8]
heapify(name_list)
for i in range(len(name_list)):
    print(heappop(name_list))

最後までご覧いただきありがとうございました
よかったらLGTM(Looks Good To Me)くださ~い
間違いあったら、ご指摘くださ~い

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?