Reputation: 1139
I'm playing around with some basic card/deck manipulations in python. Below you can see my Card class and Deck class. Assume that I know that some cards are dead and would like to remove them from the deck.
import itertools
SUIT_LIST = ("h", "s", "d", "c")
NUMERAL_LIST = ("2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A")
class Card:
def __init__(self, numeral, suit):
self.numeral = numeral
self.suit = suit
self.card = self.numeral, self.suit
def __repr__(self):
return self.numeral + self.suit
class Deck(set):
def __init__(self):
for numeral, suit in itertools.product(NUMERAL_LIST, SUIT_LIST):
self.add(Card(numeral, suit))
deck = Deck()
dead_card = Card('J','s')
deck.remove(dead_card)
Raises the following error:
Traceback (most recent call last):
File "<ipython-input-93-06af62ea1273>", line 23, in <module>
deck.remove(dead_card)
KeyError: Js
What is the proper way of removing dead cards from my deck? And why the way I do it does not work?
Upvotes: 3
Views: 613
Reputation: 363073
You'll need two new methods on your Card
class, for membership in sets and dicts to work sanely:
class Card:
...
def __hash__(self):
return hash(self.card)
def __eq__(self, other):
if isinstance(other, Card):
return self.card == other.card
return NotImplemented
This is because sets are implemented with hash tables, and unless you define how to hash and compare instances of your custom class, a hash based on the identity (memory location in CPython) will be used as a default. Using id
provides a fairly crappy default here - two cards with same number/suit would not be considered "equal" and the membership in a Deck
is not recognised.
Upvotes: 5