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))
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)
well, you just needed one more level of list.
deck = [[x+y for x in value] for y in deck_types]
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']]
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))
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)
well, you just needed one more level of list.
deck = [[x+y for x in value] for y in deck_types]
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']]