Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Python Mutability issue

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..
Python:
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[i]] = [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
 
The issue you're facing is related to the fact that copy() creates a shallow copy, meaning it creates a new dictionary object, but the inner lists (values in your case) are still references to the same lists in memory. To create a deep copy, where the inner lists are also duplicated and not shared, you can use the copy module's deepcopy() function.
Here's how you can modify your code to use 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] = card_numbers.copy()

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


This modification uses deepcopy to create a new dictionary with a fully independent copy of the inner lists. Now, modifying available_cards will not affect full_deck.
 

New Threads

Buy us a coffee!

Back
Top Bottom