Getting the cartesian product of two lists as a list-of-lists

Question:

I am a beginner with Python.

I have been struggling with creating a proper list comprehension for my deck of cards. I want to create four lists within a list where each "number index" has the fitting type. I’ll try to show below.

This is what I want:

deck = [["1 Hearts, "2H", ..."13H"], ["1 Diamonds", "2D", ..."13D"], [....], [...]]

This is what I have:

value = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
deck_types = ["hearts", "diamonds", "clubs", "spades"]
deck = [[i] + value for i in deck_types]

Output:

I can’t post images because my reputation is below 10, but I will describe it.

[["hearts", "1", "2", "3"....], ["Diamonds", "1", "2", "3"....], ["Clubs", "1"...], [....]]

As you can see, it’s not exactly what I want. Each type becomes the nr [0] in every sublist. My plan is to combine the .pop() function with random.randint for card draw. So that when the first player draws a card, that card will be removed from the deck. Then the second player will not be able to draw the same card. When I then print the first players’ card, I want to be able to see both type and number. Thus far I have only been able to see the number.

Like this:

card1 = deck[random.randint(1, 3)].pop(random.randint(2, 13))
card2 = deck[random.randint(1, 3)].pop(random.randint(2, 13))
Asked By: Kenso33

||

Answers:

So, I don’t think you can do this in one single list comprehension, because it requires 2 loops. Here is the deconstructed version.

values = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
deck = []
card_suits = ["hearts", "diamonds", "clubs", "spades"]
for suit in card_suits:
    suit_deck = []
    for number in values:
        card = f"{number} {suit}"
        suit_deck.append(card)
    deck.append(suit_deck)
    
print(deck)
[['1 hearts', '2 hearts', '3 hearts', '4 hearts', '5 hearts', '6 hearts', '7 hearts', '8 hearts', '9 hearts', '10 hearts', '11 hearts', '12 hearts', '13 hearts'], ['1 diamonds', '2 diamonds', '3 diamonds', '4 diamonds', '5 diamonds', '6 diamonds', '7 diamonds', '8 diamonds', '9 diamonds', '10 diamonds', '11 diamonds', '12 diamonds', '13 diamonds'], ['1 clubs', '2 clubs', '3 clubs', '4 clubs', '5 clubs', '6 clubs', '7 clubs', '8 clubs', '9 clubs', '10 clubs', '11 clubs', '12 clubs', '13 clubs'], ['1 spades', '2 spades', '3 spades', '4 spades', '5 spades', '6 spades', '7 spades', '8 spades', '9 spades', '10 spades', '11 spades', '12 spades', '13 spades']]

Or one using a list comprehension for each suit_deck

values = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
deck = []
card_suits = ["hearts", "diamonds", "clubs", "spades"]
for suit in card_suits:
    suit_deck = [f"{number} {suit}" for number in values]
    deck.append(suit_deck)
    
print(deck)
    
Answered By: Lauren Boland

well, you just needed one more level of list.

deck = [[x+y for x in value] for y in deck_types]
Answered By: najeem
values = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]
card_suits = ["hearts", "diamonds", "clubs", "spades"]
[[f"{number} {suit}" for number in values] for suit in card_suits]

[['1 hearts',
  '2 hearts',
  '3 hearts',
  '4 hearts',
  '5 hearts',
  '6 hearts',
  '7 hearts',
  '8 hearts',
  '9 hearts',
  '10 hearts',
  '11 hearts',
  '12 hearts',
  '13 hearts'],
 ['1 diamonds',
  '2 diamonds',
  '3 diamonds',
  '4 diamonds',
  '5 diamonds',
  '6 diamonds',
  '7 diamonds',
  '8 diamonds',
  '9 diamonds',
  '10 diamonds',
  '11 diamonds',
  '12 diamonds',
  '13 diamonds'],
 ['1 clubs',
  '2 clubs',
  '3 clubs',
  '4 clubs',
  '5 clubs',
  '6 clubs',
  '7 clubs',
  '8 clubs',
  '9 clubs',
  '10 clubs',
  '11 clubs',
  '12 clubs',
  '13 clubs'],
 ['1 spades',
  '2 spades',
  '3 spades',
  '4 spades',
  '5 spades',
  '6 spades',
  '7 spades',
  '8 spades',
  '9 spades',
  '10 spades',
  '11 spades',
  '12 spades',
  '13 spades']]
Answered By: Lauren Boland