1

Im having a problem with this python code:

card_list = ["1P", "1C", "1O","1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", 
     "3E", "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O", 
     "6E", "7P", "7C", "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP", 
     "DC", "DO", "DE", "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE", 
     "1P", "1C", "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", "3E", 
     "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O", "6E", "7P", "7C", 
     "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP", "DC", "DO", "DE", 
     "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE", "1P", "1C", 
     "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", "3E", "4P", "4C", "4O", "4E", 
     "5P", "5C", "5O", "5E", "6P", "6C", "6O", "6E", "7P", "7C", "7O", "7E", "8P", "8C", 
     "8O", "8E", "9P", "9C", "9O", "9E", "DP", "DC", "DO", "DE", "JP", "JC", "JO", "JE", 
     "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE"]

#print all cards
print card_list

#cards from a deck
cards_deck = ["1P", "1C", "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", 
     "3E", "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O", 
     "6E", "7P", "7C", "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP", 
     "DC", "DO", "DE", "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE"]

#remove deck cards from card pool
final_card= list(set(card_list).difference(set(cards_deck)))

#print remaining cards
print final_card

In the end it should just remove one "1P", one "1C", etc but it ends up removing all them and shows an empty array. Anyway I can just show the remaining cards?

The objective is having a big pool of cards, and from that big pool keep removing "cards_deck" like its forming decks until its not possible anymore.

How can I do this?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
lordvader
  • 35
  • 6
  • 1
    Does `card_list` have to be a list, i.e. does the order of the elements matter? Removing elements from it would be very efficient if you could represent it as a set or dict instead. – Aran-Fey Oct 29 '18 at 11:19
  • How would you draw cards from a deck in real life? `random.shuffle` the deck, then `pop` cards from the deck into your list. – tobias_k Oct 29 '18 at 11:21
  • 1
    You are getting the empty list because all cards are present in both the sets. Therefore difference is always empty – Vineeth Sai Oct 29 '18 at 11:22
  • Or represent your `card_list` using a `collections.Counter`, mapping card-types to counts. – tobias_k Oct 29 '18 at 11:22
  • @Aran-Fey no, it doesn't matter as long as I can put those elements inside. – lordvader Oct 29 '18 at 11:23
  • You can subtract two lists https://stackoverflow.com/questions/3462143/get-difference-between-two-lists – Grzegorz Eleryk Oct 29 '18 at 11:34
  • You can subtract two sets like there: https://stackoverflow.com/questions/3462143/get-difference-between-two-lists – Grzegorz Eleryk Oct 29 '18 at 11:47

3 Answers3

1

As @tobias_k mentioned you could use Counter:

from collections import Counter

card_list = ["1P", "1C", "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O",
             "3E", "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O",
             "6E", "7P", "7C", "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP",
             "DC", "DO", "DE", "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE",
             "1P", "1C", "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", "3E",
             "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O", "6E", "7P", "7C",
             "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP", "DC", "DO", "DE",
             "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE", "1P", "1C",
             "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O", "3E", "4P", "4C", "4O", "4E",
             "5P", "5C", "5O", "5E", "6P", "6C", "6O", "6E", "7P", "7C", "7O", "7E", "8P", "8C",
             "8O", "8E", "9P", "9C", "9O", "9E", "DP", "DC", "DO", "DE", "JP", "JC", "JO", "JE",
             "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE"]

# print all cards
print card_list

# cards from a deck
cards_deck = ["1P", "1C", "1O", "1E", "2P", "2C", "2O", "2E", "3P", "3C", "3O",
                  "3E", "4P", "4C", "4O", "4E", "5P", "5C", "5O", "5E", "6P", "6C", "6O",
                  "6E", "7P", "7C", "7O", "7E", "8P", "8C", "8O", "8E", "9P", "9C", "9O", "9E", "DP",
                  "DC", "DO", "DE", "JP", "JC", "JO", "JE", "VP", "VC", "VO", "VE", "RP", "RC", "RO", "RE"]

counts = Counter(card_list)

while counts:

    # remove deck cards from card pool
    for card in cards_deck:
        counts[card] -= 1
        if counts[card] == 0:
            counts.pop(card)

    final_card = [card for card in counts.elements()]

    # print remaining cards
    print final_card

Output

['1P', '1C', '1O', '1E', '2P', '2C', '2O', '2E', '3P', '3C', '3O', '3E', '4P', '4C', '4O', '4E', '5P', '5C', '5O', '5E', '6P', '6C', '6O', '6E', '7P', '7C', '7O', '7E', '8P', '8C', '8O', '8E', '9P', '9C', '9O', '9E', 'DP', 'DC', 'DO', 'DE', 'JP', 'JC', 'JO', 'JE', 'VP', 'VC', 'VO', 'VE', 'RP', 'RC', 'RO', 'RE', '1P', '1C', '1O', '1E', '2P', '2C', '2O', '2E', '3P', '3C', '3O', '3E', '4P', '4C', '4O', '4E', '5P', '5C', '5O', '5E', '6P', '6C', '6O', '6E', '7P', '7C', '7O', '7E', '8P', '8C', '8O', '8E', '9P', '9C', '9O', '9E', 'DP', 'DC', 'DO', 'DE', 'JP', 'JC', 'JO', 'JE', 'VP', 'VC', 'VO', 'VE', 'RP', 'RC', 'RO', 'RE', '1P', '1C', '1O', '1E', '2P', '2C', '2O', '2E', '3P', '3C', '3O', '3E', '4P', '4C', '4O', '4E', '5P', '5C', '5O', '5E', '6P', '6C', '6O', '6E', '7P', '7C', '7O', '7E', '8P', '8C', '8O', '8E', '9P', '9C', '9O', '9E', 'DP', 'DC', 'DO', 'DE', 'JP', 'JC', 'JO', 'JE', 'VP', 'VC', 'VO', 'VE', 'RP', 'RC', 'RO', 'RE']
['1P', '1P', 'DO', 'DO', '3P', '3P', 'JP', 'JP', '5P', '5P', 'VC', 'VC', '3C', '3C', '1C', '1C', 'JO', 'JO', '1E', '1E', '5E', '5E', 'JE', 'JE', '8E', '8E', '3E', '3E', 'JC', 'JC', '7E', '7E', '2O', '2O', '7C', '7C', '9O', '9O', '7O', '7O', '9C', '9C', '9E', '9E', 'RE', 'RE', '5C', '5C', '7P', '7P', '9P', '9P', 'RO', 'RO', 'DE', 'DE', '2P', '2P', 'VE', 'VE', 'RC', 'RC', '4P', '4P', 'DC', 'DC', 'VP', 'VP', '4O', '4O', '2C', '2C', 'RP', 'RP', '4E', '4E', '4C', '4C', '8O', '8O', '1O', '1O', '6C', '6C', '6E', '6E', 'DP', 'DP', '2E', '2E', '8C', '8C', '5O', '5O', '6O', '6O', '6P', '6P', 'VO', 'VO', '3O', '3O', '8P', '8P']
['1P', 'DO', '3P', 'JP', '5P', 'VC', '3C', '1C', 'JO', '1E', '5E', 'JE', '8E', '3E', 'JC', '7E', '2O', '7C', '9O', '7O', '9C', '9E', 'RE', '5C', '7P', '9P', 'RO', 'DE', '2P', 'VE', 'RC', '4P', 'DC', 'VP', '4O', '2C', 'RP', '4E', '4C', '8O', '1O', '6C', '6E', 'DP', '2E', '8C', '5O', '6O', '6P', 'VO', '3O', '8P']
[]

Explanation

The idea is to decrease the count of each card in card_deck for each iteration of the while loop until you have no cards present in counts. When the count of a card gets to 0 remove it from counts.

Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
0

The reason for your problem is that set takes distinct elements from the list and hence you end up subtracting two sets of distinct elements which have all the elements common among them. Hence your set difference is an empty set.

You can solve your problem as such.

final_card = filter(None, [each if each not in cards_deck else cards_deck.remove(each) for each in card_list ])

EDIT :

To find the total number of decks you can make from the cards.

from collections import Counter
card_counter = Counter(card_list)
check_if_all_cards_exist = set(card_list).difference(cards_deck)
if check_if_all_cards_exist:
   number_of_decks = min(card_counter.values())
else:
   number_of_decks = 0
Kenstars
  • 662
  • 4
  • 11
  • Thanks, that worked. Any way I can keep removing until its possible to build a deck? – lordvader Oct 29 '18 at 11:29
  • To stop removing at the point where you can no longer build a deck with the remaining cards, you need to slightly modify the code. I would suggest you to listn to What tobias mentioned and use a Counter in the case. – Kenstars Oct 29 '18 at 11:33
0

Hope this answers your problem. I've created a new list which only consists the elements which are not present in cards_deck.

print("CARDLIST:",len(card_list))
print("CARD_DECK:",len(cards_deck))

final_card = [card_list[card_list.index(card)] for card in cards_deck if card in card_list]

print("AFTER DIFFERENCE:" ,len(card_list) - len(final_card))

print(final_card)

Output:

CARDLIST: 156
CARD_DECK: 51
AFTER DIFFERENCE: 105
['7E', '1P', '1C', '1O', '1E', '2P', '2C', '2O', '2E', '3P', '3C', '3O', '3E', '4P', '4C', '4O', '4E', '5P', '5C', '5O', '5E', '6P', '6C', '6O', '6E', '7P', '7C', '7O', '7E', '8P', '8C', '8O', '8E', '9P', '9C', '9O', '9E', 'DP', 'DC', 'DO', 'DE', 'JP', 'JC', 'JO', 'JE', 'VP', 'VC', 'VO', 'VE', 'RP', 'RC', 'RO', 'RE', '1P', '1C', '1O', '1E', '2P', '2C', '2O', '2E', '3P', '3C', '3O', '3E', '4P', '4C', '4O', '4E', '5P', '5C', '5O', '5E', '6P', '6C', '6O', '6E', '7P', '7C', '7O', '7E', '8P', '8C', '8O', '8E', '9P', '9C', '9O', '9E', 'DP', 'DC', 'DO', 'DE', 'JP', 'JC', 'JO', 'JE', 'VP', 'VC', 'VO', 'VE', 'RP', 'RC', 'RO', 'RE']
Vineeth Sai
  • 3,389
  • 7
  • 23
  • 34