2

I'm trying to make a abnormal deck of cards. Each card will have a color (red, green or blue), a degree (1, 2 or 3), a symbol (triangle, square or circle) and a number (1,2 or 3). I have a class that looks like this:

class card:
    def __init__(self, color, degree, symbol, number):
        self.color = color
        self.degree = degree
        self.symbol = symbol
        self.number = number
    
    def __repr__(self):
        return "(%s,%s,%s,%s)" %(self.color, self.degree, self.symbol, self.number)

I also have the following lists containg all the possible values for the fields and an empty deck where I want the cards to get into.

colors = ["red", "green", "blue"]
degrees = ["1", "2", "3"]
symbols = ["triangle", "square", "circle"]
numbers = ["1", "2", "3"]
deck = []

I want to create a full deck with every possible card. Preferably, they would be in a random order, but that's not necessary. I know that if it was only a number and color, I could easily do it this way:

deck = [card(value, color) for value in range(0, 2) for color in colors]

But I can't figure out how to do it with a symbol and a degree as well. I tried to build on more if statements to loop all the list, but that didn't work. I also don't want the same card to appear twice, and I dont want a card that doesn't follow the class rules: they must all be strutured as [color, degree, symbol, number].

Does anyone have a idea how to do this this?

The_spider
  • 1,202
  • 1
  • 8
  • 18
effa94
  • 31
  • 5

4 Answers4

2

Full deck with every possible card combination:

deck = [card(color, degree, symbol, number) for color in colors \
        for degree in degrees for symbol in symbols for number in numbers]

For randomizing the card order in the deck, take a look at this: Shuffling a list of objects

fabio.avigo
  • 308
  • 1
  • 13
1

use product from itertools

import itertools


deck = [
    card(color, degree, symbol, number)
    for color, degree, symbol, number in
    itertools.product(colors, degrees, symbols, numbers)
]
Mohit Solanki
  • 2,122
  • 12
  • 20
0

Do you want all combinations of colors, degrees, symbols and numbers?

If so, use nested for loops:

deck = []
for color in colors:
    for degree in degrees:
        for symbol in symbols:
            for number in numbers:
                deck.append(card(color, degree, symbol, number)

# Also written as a list comprehension
deck = [
    card(color, degree, symbol, number)
    for color in colors
        for degree in degrees
            for symbol in symbols
                for number in numbers
]  # The indent is just to show how it works. For style, put them all at the same indent.

Or use itertools.product (Which can also be lazy)

deck = itertools.starmap(card, itertools.product(colors, degrees, symbols, numbers))

deck = list(deck)  # If you really need it to be a list
Artyer
  • 31,034
  • 3
  • 47
  • 75
  • I tried the first loop there, however it only gave me 29 cards, while i was expecting the entire deck to contain 81. why isnt there more of them? I couldnt get the second example there to work, since im using a main function which calls upon this function that makes the deck, and then it wouldnt recognize the deck object, same problem when i tried the itertools things. – effa94 Sep 26 '18 at 12:41
  • @effa94 if you want to edit the deck list in place, use `deck[:] = newdeck`. This will bring the new deck list into the old one, allowing it to continue using the old list outside the function. Alternatively, you could return the new deck such that it can be used instead of the old one. – The_spider Aug 29 '23 at 09:47
-1
import itertools

identifiers = [colors, degrees, symbols, numbers]
deck = [[*i] for i in itertools.product(*identifiers)]
[['red', '1', 'triangle', '1'], ['red', '1', 'triangle', '2'], ['red', '1', 'triangle', '3'],...
vash_the_stampede
  • 4,590
  • 1
  • 8
  • 20