0

I am probably not using dictionaries right but anyway, here is what I was trying to do:

  1. Set up a starting dictionary. This would be used as an empty template.
  2. pass the dictionary to a function. In the function it will be assigned a new variable name so I can do things to it.
  3. work on the dictionary by adding items to it.
  4. return the dictionary to some other variable in the main code.
  5. repeat the above for another variable in the main code. each time taking in that template dictionary and doing things to it.

But what seems to happen is that the "starting" dictionary is updated as well so when I pass it for the second time, its full of information I don't want.

Here is a minimum example:

startDeck = {
  "deckSize":0,
  "score":0,
  "blackjack":False,
}


def playBlackjack(deck):
  userDeck = dealCards(cards= deck,count=2)
  compDeck = dealCards(cards= deck,count=1)

def dealCards(cards,count):
  
  score = cards["score"]
  deckSize = cards["deckSize"]
  
  for n in range(count):
    newCard = {}
    deckSize+=1
    score+=1
    cardNo = "card" + str(deckSize)

    newCard["card"] = "hearts"
    newCard["value"] = 10
    newCard["suit"] = "clubs"
    cards[cardNo]=newCard

  cards["score"]=score
  cards["deckSize"]=deckSize

  return cards


playBlackjack(startDeck)

I think that should work. I know it probably won't make much sense and maybe I should not be using dictionaries, but I did struggle with them and wanted to have a go with them to understand more.

But essentially what is happening here is all the dictionaries, whether its that "startDeck" one at the top (which I thought would be global and thus available to any function but I keep getting told by python that it can't see it?) or the dictionaries that I thought would only exist while the function runs, all end up filled with exactly the same information. And I don't understand why.

  • 3
    Does this answer your question? [How to copy a dictionary and only edit the copy](https://stackoverflow.com/questions/2465921/how-to-copy-a-dictionary-and-only-edit-the-copy) – slothrop Jun 27 '23 at 12:49
  • 1
    Your `dealCards` function should not perform multiple things such as making the deck as well as dealing the cards. This creates a confluct of interest in which you could be dealing the same card(s) to each user which would not be desired. In python you will rarely, if ever, need to make an empty container and then fill it. Have a function to make the deck, use that function once to get the deck, and then use another function to deal cards from the deck to a user. – Jab Jun 27 '23 at 12:56
  • 1
    Also, since you asked if you're using dict's correctly here, I'd say to use classes here instead of dicts because you could just have the functions that apply to a deck like creating the cards and dealing them be a part of the deck class and then a card class with comparison and equality check functions. But since you want to want to learn dict's then that's fine just know there are better ways to do this – Jab Jun 27 '23 at 13:02
  • @Jab Yes I see what you're saying about what the function is doing. For what I am doing here I am just concerned with filling the dictionary with cards and handling the dictionaries. I will take a look at classes, though we haven't covered those yet, so want to stick to tools we've covered so far. I suspect this task is meant to be achieved using lists (and I would have done it by now) but dictionaries is where I got stuck so wanted to see if I could do it all with those as a way to better understand. – Otispunkmeyer86 Jun 27 '23 at 13:42
  • @slothrop actually yes this looks like the ticket I need. Thanks, will give it a more thorough read now. – Otispunkmeyer86 Jun 27 '23 at 13:43
  • @Otispunkmeyer86 cool, another good follow-up read is https://nedbatchelder.com/text/names.html – slothrop Jun 27 '23 at 16:58

1 Answers1

1

This is because the dictionary is passed as a reference. You can learn more by Googling "Reference vs value types", there are plenty of resources about the topic.
It's a basic programming concept which is important to understand in order to be aware of what object you're manipulating (especially with Python as it will do stuff, where other languages might complain). And it's a powerful tool when used wisely.

To sum up your issue quickly, Python doesn't create a new object in your function playBlackJack, because dictionaries are part of reference types.

To have a copy of the dictionary, you can have:

from copy import deepcopy

def playBlackjack(initial_deck):
  deck = deecopy(initial_deck)
  userDeck = dealCards(cards=deck,count=2)
  compDeck = dealCards(cards=deck,count=1)
Jboulery
  • 238
  • 2
  • 9
  • Thanks. Between this and the link posted above by @slothrop I think I understand it now. This was not something made clear on the course I am using. Then again, it is probably a bit beyond beginner. I just presumed dictionaries worked like variables. That is if I put ```A = dictionary1``` and then ```B = A``` I would effectively have a copy of the dictionary in ```B``` that I could use to do things whilst maintaining the original in A. But looks like this actually works the other way round in that I am actually saying ```dictionary1 = both A and B``` – Otispunkmeyer86 Jun 27 '23 at 16:26
  • 2
    All types in Python function as (loosely speaking) "reference types". However, some types are immutable (for example int, float, string and tuple), so you don't encounter problems like this with them, because it's not possible to change the value of existing objects. See: https://nedbatchelder.com/text/names.html – slothrop Jun 27 '23 at 17:42
  • 1
    Nice addition @slothrop – Jboulery Jul 04 '23 at 17:31