[파이썬] 데이터 모델

Fluent Python 책을 보고 정리

파이썬 카드 한벌

예제 1-1

import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    suits ='spades diamonds clubs hearts'.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, position):
        return self._cards[position]

__len__ 메소드

len() 함수로 FrenchDeck를 호출하면 FrenchDeck.__len__() 이 호출된다. __len__은 던더 len 메소드라고 부른다(던더=double under)

deck = FrenchDeck()
len(deck) # 52

__getitem__ 메소드

__getitem__ 메소드는 self._cards의 [] 연산자에 작업을 위임한다.
>>> deck[0]
Card(rank='2', suit='hearts')

>>> deck[-1]
Card(rank='A', suit='hearts')
deck객체는 []를 지원하므로 슬라이싱도 지원한다.
# 앞에 3개의 카드 가져오기
>>> deck[:3]
[Card(rank='2', suit='hearts'),
Card(rank='3', suit='hearts'),
Card(rank='4', suit='hearts')]

# 12번 인덱스에서 13개씩 건너뛰어 에이스만 가져오기
>>> deck[12::13]
[Card(rank='A', suit='spades'),
Card(rank='A', suit='diamonds'),
Card(rank='A', suit='clubs'),
Card(rank='A', suit='hearts')]
deck객체는 []를 지원하므로 랜덤 선택 random.choice를 지원
>>> from random import choice
>>> choice(deck)
Card(rank='3', suit='hearts')
deck객체는 []를 지원하므로 랜덤 선택 reversed를 지원
>>> for card in reversed(deck):
>>>     print(card)
Card(rank='2', suit='spades')
Card(rank='3', suit='spades')
Card(rank='4', suit='spades')
...
in 연산자

__contains__() 메소드가 없다면 in 연산자는 차례대로 검색한다.

>>> Card('Q', 'hearts') in deck
True
>>> Card('7', 'beasts') in deck
False
정렬
suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)
def spades_high(card):
    rank_value = FrenchDeck.ranks.index(card.rank)
    return rank_value * len(suit_values) + suit_values[card.suit]
>>> for card in sorted(deck, key=spades_high):
>>>     print(card)