Python で switch 文

if-elif-else 文を使う

上のブログ記事でも既に、if 文使って条件分岐するのはクールじゃないぜ、と書いてある。以下は if と別れる50の方法《31》switch は百害あって一理なし - 続・ひよ子のきもち に書いてあったサンプルコード。確かにちょっと長い。

class Card:
    JOKER   = 0 
    SPADE   = 1 
    DIAMOND = 2 
    CLUB    = 3 
    HEART   = 4 

    def __init__(self, suit, number):
        self.suit = suit
        self.number = number

    def __str__(self):
        s = []
        if self.number > 0:
            if   self.suit == self.SPADE:
                s.append("S")
            elif self.suit == self.DIAMOND:
                s.append("D")
            elif self.suit == self.CLUB:
                s.append("C")
            elif self.suit == self.HEART:
                s.append("H")
            else:
                pass

            if   self.number == 1:
                s.append("A")
            elif self.number == 10: 
                s.append("O")
            elif self.number == 11: 
                s.append("J")
            elif self.number == 12: 
                s.append("Q")
            elif self.number == 13: 
                s.append("K")
            else:
                s.append(str(self.number))    
        else:
            s.append("JK")
        return "".join(s)

if __name__ == '__main__':
    cards = []
    for number in range(1, 13+1):
        cards.append(Card(Card.SPADE, number))
        cards.append(Card(Card.DIAMOND, number))
        cards.append(Card(Card.CLUB, number))
        cards.append(Card(Card.HEART, number))
    cards.append(Card(0, Card.JOKER))

    for n, e in enumerate(cards):
        print e,
        if n%4 == 3:
            print

実行結果。

$ python card.py 
SA DA CA HA
S2 D2 C2 H2
S3 D3 C3 H3
S4 D4 C4 H4
S5 D5 C5 H5
S6 D6 C6 H6
S7 D7 C7 H7
S8 D8 C8 H8
S9 D9 C9 H9
SO DO CO HO
SJ DJ CJ HJ
SQ DQ CQ HQ
SK DK CK HK
JK

辞書オブジェクト(dict)を使う

上のソースを書きかてみたのが以下。

class Card:
    JOKER   = 0 
    SPADE   = 1 
    DIAMOND = 2 
    CLUB    = 3 
    HEART   = 4 

    def __init__(self, suit, number):
        self.suit = suit
        self.number = number

    def __str__(self):
        s = []
        switch_suit = {0:'J', 1:'S', 2:'D', 3:'C', 4:'H'}
        switch_number = {0:'K', 1:'A', 10:'O', 11:'J', 12:'Q', 13:'K'}
        s.append(switch_suit[self.suit])
        s.append(switch_number.get(self.number, str(self.number)))
        return ''.join(s)

if __name__ == '__main__':
    cards = []
    for number in range(1, 13+1):
        cards.append(Card(Card.SPADE, number))
        cards.append(Card(Card.DIAMOND, number))
        cards.append(Card(Card.CLUB, number))
        cards.append(Card(Card.HEART, number))
    cards.append(Card(0, Card.JOKER))

    for n, e in enumerate(cards):
        print e,
        if n%4 == 3:
            print

これでかなり短くなった。前のソースの名残でまだ冗長な部分が多少残ってるが、逆にコードの可読性をあげるためには、数字の部分を self.JOKER に書き換えたりしてわかりやすくしたほうがいいのかもしれない。

あと、辞書オブジェクトの get メソッドはかなり便利だと思った。「辞書オブジェクト.get(キー, 値)」で、キーが登録されている場合は「辞書オブジェクト[キー]」を返し、キーが登録されていない場合は、値を返す。