【Python 雑談・雑学 + coding challenge】sorted 組み込み関数の key パラメータをうまく使って、カスタムオブジェクトを簡単にソートしよう! __getitem__、__len__ 特殊関数 ( special methods, dunder methods ) を実装すれば立派なシーケンス ( sequence ) です 投稿一覧へ戻る

Tags: miscellaneous , challenge , python

Published 2020年8月29日7:09 by T.Tsuyoshi

唐突に coding challenge です!


問題: トランプをソート ( sort ) してください。 ( 制限時間: 25 分 )


ナナさんはトランプを 1 組持っています ( Deck クラスオブジェクト )。


妹にグチャグチャにシャッフルされてしまって途方に暮れています。


どうぞカードをソートしてあげてください。


カードの rank は 2, 3, ..., 9, 10, J, Q, K, A の順に強くなり、


カードの suit は clubs, diamonds, hearts, spades の順に強くなります。


ではお願いします (ペコリ)。


from collections import namedtuple
from random import shuffle


Card = namedtuple('Card', ['rank', 'suit'])


class Deck:
ranks = [str(n) for n in range(2, 11)] + list('JQKA')
suits = 'clubs diamonds hearts spades'.split()

def __init__(self):
self.cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]

def __len__(self):
return len(self.cards)

def __getitem__(self, pos):
return self.cards[pos]

def __setitem__(self, pos, value):
self.cards[pos] = value


deck = Deck()
shuffle(deck) # 妹よ、何ということを ...


sorted_deck = ソート関数(deck) # この部分を作成してください


print(sorted_deck[:5])

# [Card(rank='2', suit='clubs'), Card(rank='2', suit='diamonds'), Card(rank='2', suit='hearts'), Card(rank='2', suit='spades'), Card(rank='3', suit='clubs')]


print(sorted_deck[-5:])

# [Card(rank='K', suit='spades'), Card(rank='A', suit='clubs'), Card(rank='A', suit='diamonds'), Card(rank='A', suit='hearts'), Card(rank='A', suit='spades')]



さて、いかがだったでしょか?


様々な方法があると思います。


今回は Python の sorted() 組み込み関数の key パラメータに、並べ替えのための比較値を提供する自作関数を渡す、という方法で実装してみました。


気付いたでしょうか? 実は、Deck クラスの ranks リスト、suits リストとも弱い順に並んでいるんです。


ここではそれをフルに活用しています。


def sort_deck(card: Card):
"""
Deck オブジェクトをソートする際の比較値を提供する

:param card: Card型
:return: 並べ替え時の比較値となる int 値
"""

rank_value = Deck.ranks.index(card.rank) # カードの数字ごとの強さを表す数値としてリストのインデックス番号を割り当てます
return rank_value * len(Deck.suits) + Deck.suits.index(card.suit) # カードのマークの強さを表す数値としてリストのインデックス番号を利用します

sorted_deck = sorted(deck, key=sort_deck)



これだけです。


deck = Deck()

shuffle(deck)

print(deck[:5])

# [Card(rank='10', suit='spades'), Card(rank='2', suit='clubs'), Card(rank='10', suit='hearts'), Card(rank='6', suit='spades'), Card(rank='J', suit='spades')]


print(deck[-5:])
# [Card(rank='K', suit='diamonds'), Card(rank='5', suit='clubs'), Card(rank='9', suit='diamonds'), Card(rank='8', suit='spades'), Card(rank='Q', suit='spades')]


sorted_deck = sorted(deck, key=sort_deck)


print(sorted_deck[:5])

# [Card(rank='2', suit='clubs'), Card(rank='2', suit='diamonds'), Card(rank='2', suit='hearts'), Card(rank='2', suit='spades'), Card(rank='3', suit='clubs')]


print(sorted_deck[-5:])
# [Card(rank='K', suit='spades'), Card(rank='A', suit='clubs'), Card(rank='A', suit='diamonds'), Card(rank='A', suit='hearts'), Card(rank='A', suit='spades')]

この投稿をメールでシェアする

0 comments

コメントはまだありません。

コメントを追加する(不適切と思われるコメントは削除する場合があります)