FAQ
I'm writing a simple class to represent a deck of cards. Here is the
stripped down version. Notice classes Deck and Deck2. Class Deck works,
Deck2 does not. My thinking is that it should be more efficient (a la
Deck2) to pre-create the list, and then modify it, rather than appending
Cards as in Deck.

# --------------------snip--------------
class Card:
def __init__(self, rank=0, suit=0):
self.rank=rank
self.suit=suit

def __repr__(self):
r = "A23456789TJQK"[self.rank]
s = "SHCD"[self.suit]
return r+s


class Deck:
def __init__(self):
self.deck = []
for r in range(13):
for s in range(4):
self.deck.append(Card(r,s))

class Deck2:
def __init__(self):
self.deck = 52 * [Card()]
n = 0
for r in range(13):
for s in range(4):
self.deck[n].rank = r
self.deck[n].suit = s
n = n + 1


a = Deck()
print "A --> ", a.deck
b = Deck2()
print "B --> ", b.deck
# ------------snap---------------------

Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
52 of the same card, all rank 12, suit 3.

What am I missing???

Thanks!
Nick.

Search Discussions

  • Robert Kern at Oct 28, 2004 at 10:09 pm

    Nick wrote:

    class Deck2:
    def __init__(self):
    self.deck = 52 * [Card()]
    Here you are creating a single Card instance and putting the same object
    into a list 52 times. Each slot in the list points to the same object.

    Another lesson to take away from this: Don't optimize prematurely. The
    simplest implementation should be fine unless proven otherwise via
    profiling.

    --
    Robert Kern
    rkern at ucsd.edu

    "In the fields of hell where the grass grows high
    Are the graves of dreams allowed to die."
    -- Richard Harter
  • Daniel Fackrell at Oct 28, 2004 at 10:13 pm
    "Nick" <mediocre_person at hotmail.com> wrote in message
    news:418169ec$1_1 at alt.athenanews.com...
    I'm writing a simple class to represent a deck of cards. Here is the
    stripped down version. Notice classes Deck and Deck2. Class Deck works,
    Deck2 does not. My thinking is that it should be more efficient (a la
    Deck2) to pre-create the list, and then modify it, rather than appending
    I strongly suspect premature optimization here.
    Cards as in Deck.

    # --------------------snip--------------
    class Card:
    def __init__(self, rank=0, suit=0):
    self.rank=rank
    self.suit=suit

    def __repr__(self):
    r = "A23456789TJQK"[self.rank]
    s = "SHCD"[self.suit]
    return r+s


    class Deck:
    def __init__(self):
    self.deck = []
    for r in range(13):
    for s in range(4):
    self.deck.append(Card(r,s))

    class Deck2:
    def __init__(self):
    self.deck = 52 * [Card()]
    This creates a list of 52 references to the card created by Card().
    n = 0
    for r in range(13):
    for s in range(4):
    self.deck[n].rank = r
    self.deck[n].suit = s
    n = n + 1


    a = Deck()
    print "A --> ", a.deck
    b = Deck2()
    print "B --> ", b.deck
    # ------------snap---------------------

    Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
    52 of the same card, all rank 12, suit 3.

    What am I missing???

    Thanks!
    Nick.
    How about a list comprehension?

    class Deck3:
    def __init__(self):
    self.deck = [Card(r, s) for s in range(4) for s in range(13)]
  • Larry Bates at Oct 28, 2004 at 10:16 pm

    Nick wrote:
    I'm writing a simple class to represent a deck of cards. Here is the
    stripped down version. Notice classes Deck and Deck2. Class Deck works,
    Deck2 does not. My thinking is that it should be more efficient (a la
    Deck2) to pre-create the list, and then modify it, rather than appending
    Cards as in Deck.

    # --------------------snip--------------
    class Card:
    def __init__(self, rank=0, suit=0):
    self.rank=rank
    self.suit=suit

    def __repr__(self):
    r = "A23456789TJQK"[self.rank]
    s = "SHCD"[self.suit]
    return r+s


    class Deck:
    def __init__(self):
    self.deck = []
    for r in range(13):
    for s in range(4):
    self.deck.append(Card(r,s))

    class Deck2:
    def __init__(self):
    self.deck = 52 * [Card()]
    n = 0
    for r in range(13):
    for s in range(4):
    self.deck[n].rank = r
    self.deck[n].suit = s
    n = n + 1


    a = Deck()
    print "A --> ", a.deck
    b = Deck2()
    print "B --> ", b.deck
    # ------------snap---------------------

    Deck A looks right, 52 cards, one of each. Deck B, on the other hand, is
    52 of the same card, all rank 12, suit 3.

    What am I missing???

    Thanks!
    Nick.
    self.deck = 52 * [Card()]

    Problem is with this line. It doesn't do what you want.

    Try this from interpreter prompt:

    class card:
    pass

    deckR*[card()]
    id(deck[0])
    id(deck[1])
    ...

    You will notice that all 52 entries in the list point
    to the same instance of the card class.

    As far as performance is concerned you are doing what
    is commonly called as premature optimization. I set
    up a loop and complete deck creation takes only 0.00015
    seconds (that's 0.15 milliseconds) on my machine. I
    wouldn't worry about optimizing this part of the program.

    -Larry
  • Alex Martelli at Oct 28, 2004 at 11:04 pm
    Nick wrote:
    ...
    I'm writing a simple class to represent a deck of cards. Here is the
    stripped down version. Notice classes Deck and Deck2. Class Deck works,
    Deck2 does not. My thinking is that it should be more efficient (a la
    Deck2) to pre-create the list, and then modify it, rather than appending
    Cards as in Deck.
    Everybody's accusing you of premature optimization, and they have a
    point, but, there IS a very simple approach that's fast and useful
    (particularly in Python 2.4 -- if you're interested in performance, get
    and use 2.4 beta 1 *NOW*!!!-): a list comprehension:

    self.deck = [Card(r, s) for r in xrange(13) for s in xrange(4)]


    Alex
  • Nick at Oct 28, 2004 at 11:05 pm

    Nick wrote:
    I'm writing a simple class to represent a deck of cards. Here is the
    stripped down version. Notice classes Deck and Deck2. Class Deck works,
    Deck2 does not. My thinking is that it should be more efficient (a la
    Deck2) to pre-create the list, and then modify it, rather than appending
    Cards as in Deck.
    Thanks for the replies... I smack my head in dismay.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedOct 28, '04 at 9:51p
activeOct 28, '04 at 11:05p
posts6
users5
websitepython.org

People

Translate

site design / logo © 2021 Grokbase