Mutability issue

Joined
Jul 20, 2023
Messages
56
Reaction score
2
Hey guys. I just started writing a blackjack game and it wasn't long at all before I ran into the mutability issue that I'm having. I thought I had it all figured out already before I started the project. But apparently not. Heres what I got so far. I created a deck of cards with a dictionary. The keys are the 4 suits. And the values for each key are obviously the 13 card faces of the cards. I called this "full_deck". I then made a copy called "available_cards" so that I can remove cards from it without affecting the "full_deck" reference. But when I remove cards from the "available_cards" it does in fact also remove from the "full_deck". I thought the way around this was to use the .copy() method instead of just an = assignment but now I see thats not true. I asked chat-gpt and it told me that the issue is that the .copy() method only does a shallow copy and in order to do a deep copy it recommended importing the "copy" module. Which is cool. That seams like a fine way to go. But I just want to make sure with you guys. Is that really the best way to go? Do you need to import a module or is there another way? Heres a cut down version of what Im working with..
from random import randint

card_numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
suits = ["hearts", "clubs", "spades", "diamonds"]
full_deck = {}
for i in range(len(suits)):
full_deck[suits] = [x for x in card_numbers]
available_cards = full_deck.copy()

while True:
suit = randint(0, 3)
card = randint(0, 12)
available_cards[suits[suit]].pop(card)
print(f'{card_numbers[card]} of {suits[suit]}')
print('Full Deck:')
print('\n'.join([f'{k}: {v}' for k, v in full_deck.items()]))
print()
print('Available Cards:')
print('\n'.join([f'{k}: {v}' for k, v in available_cards.items()]))
print()
print(f'Card picked: {card_numbers[card]} of {suits[suit]}')
ans = input('Press ENTER or (x) to quit:')
if ans.lower() == 'x':
break
 
Joined
Jan 24, 2024
Messages
36
Reaction score
6
The issue you're facing is related to the fact that copy() creates a shallow copy, and when you modify nested structures (like lists within a dictionary), changes might be reflected in the original dictionary. Using the copy module's deepcopy function is indeed a solution to create a true independent copy.
Here's your modified code using deepcopy:

Python:
from random import randint
from copy import deepcopy

card_numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
suits = ["hearts", "clubs", "spades", "diamonds"]
full_deck = {}
for suit in suits:
full_deck[suit] = [x for x in card_numbers]

available_cards = deepcopy(full_deck)

while True:
suit = randint(0, 3)
card = randint(0, 12)
    available_cards[suits[suit]].pop(card)

print(f'{card_numbers[card]} of {suits[suit]}')
print('Full Deck:')
print('\n'.join([f'{k}: {v}' for k, v in full_deck.items()]))
print()
print('Available Cards:')
print('\n'.join([f'{k}: {v}' for k, v in available_cards.items()]))
print()
print(f'Card picked: {card_numbers[card]} of {suits[suit]}')
ans = input('Press ENTER or (x) to quit:')
if ans.lower() == 'x':
break

Now, modifications to available_cards won't affect full_deck because deepcopy creates a completely independent copy. Importing the copy module for this purpose is a reasonable approach.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,717
Messages
2,569,382
Members
44,701
Latest member
OurCBDLifeSupplement

Latest Threads

Top