12
\$\begingroup\$

I want to have a deck of cards that looks like this:

['H1', 'H2', 'H3', 'H4', 'H5', 'H6'...]

For that I wrote the following code:

    import itertools
    kind = 'HCDS'
    value = ['1','2','3','4','5','6','7','8','9','10','J','Q','K','A']
    temp = list(itertools.product(kind,value))

    deck = []
    for i in range(0, len(temp)): 
        (a,b) = temp[i]
        deck.append(a+b)
    print(deck)

I was wondering if it could be done easier without the use of this temp variable or the for loop.

\$\endgroup\$
  • 2
    \$\begingroup\$ One (off-topic) suggestion - just to ease parsing and keystrokes - use "T" for 10... (eg. '9', 'T', 'Q', 'K', 'A' ]) \$\endgroup\$ – Baard Kopperud Nov 26 '16 at 20:40
  • \$\begingroup\$ Since this is code review: the proper way to do this would be to have a list of (immutable) objects with suit and value properties.. \$\endgroup\$ – BlueRaja - Danny Pflughoeft Nov 27 '16 at 2:15
  • 1
    \$\begingroup\$ @BlueRaja-DannyPflughoeft you may want to add that as an answer, so it's not lost in the comments for the next person who sees this question. I had the same thought when I was initially looking at this question. \$\endgroup\$ – Kevin Brown Nov 27 '16 at 5:00
21
\$\begingroup\$

You could just use str.join in a list comprehension and create deck directly:

import itertools 
kind = 'HCDS' 
value = ['2','3','4','5','6','7','8','9','10','J','Q','K','A']
deck = ["".join(card) for card in itertools.product(kind,value)]

Note that a regular French card set starts at 2, there is no 1.

\$\endgroup\$
10
\$\begingroup\$

You can unpack the tuple directly in the list comprehension and use + to join the cards.

In [12]: kind = 'HCDS'
In [13]: value = ['1','2','3','4','5','6','7','8','9','10','J','Q','K','A']
In [14]: deck = [k + v for k, v in itertools.product(kind, value)]
In [15]: deck[:4], deck[-4:]
Out[15]: (['H1', 'H2', 'H3', 'H4'], ['SJ', 'SQ', 'SK', 'SA'])

Also, instead of using itertools.product, you could use a double-for-loop list comprehension:

In [16]: deck = [k + v for k in kind for v in value]
In [17]: deck[:4], deck[-4:]
Out[17]: (['H1', 'H2', 'H3', 'H4'], ['SJ', 'SQ', 'SK', 'SA'])

Not that it matters much in this example, but for just joining two strings, + is quite a bit faster than join, and the double-for-loop also seems to be a bit faster then itertools.product:

In [21]: %timeit ["".join(card) for card in itertools.product(kind,value)]
10000 loops, best of 3: 80.4 us per loop
In [22]: %timeit [k + v for k, v in itertools.product(kind, value)]
10000 loops, best of 3: 42.1 us per loop
In [23]: %timeit [k + v for k in kind for v in value]
10000 loops, best of 3: 35.5 us per loop
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.