0

I am trying to create card game simulations to improve my programming skills a bit, and i am stuck with the following problem:

I have the cards in a big list, and i use the next function to pick a card and remove it from the deck.

cards= [........(big list of cards here in string format).......]
def Pickacard(x):
    rand=random.randint(0,len(x)-1)
    t=int(x[rand])
    del(x[rand])
    return t

When i use the following iteration, the deck isnt beeing renewed. Instead every time a card gets picked, the deck remains 1 item shorter, despite the fact that in every loop, i have set "test=cards" so that it sets the list back to the original.

for i in range(200):
    test=cards
    Pickacard(test)
    print(test)

Deck had 208 cards, if the deck was renewed then (print test) would give me a list of 207 cards. Instead i get a list of 8 cards. I though this would only happen if ....test=cards.... was outside of the loop.

John
  • 11
  • 1
  • 1
    Try copying the list. e.g. `test=list(cards)`. What you are doing currently is passing around a reference to the same list. When you delete from it. The change is seen in all instance that refer to that list. – Paul Rooney May 20 '16 at 04:48

3 Answers3

2

When calling test = cards you are not copying the list cards in test. In fact, what you are doing is merely copying the pointer test into cards. So they are pointing on the same list. This is why the list keeps shrinking and is never renewed.

If you want to renew it, you have several possibilities. You could created a copy of the list with the following:

  • Slice it with test = cards[:] (not the best way of doing that)
  • Create it with list(): test = list(copy)
  • Explicit copy : test = copy.copy(cards) (must import the module copy first)

Else, you can save the card you deleted and reinsert it at the end of the loop. This avoids copying the list at each iteration. Though it's not crucial in your case, it's a good practice to think a bit about performances by avoiding unnecessary computing:

def Pickacard(x):
    rand=random.randint(0,len(x)-1)
    card = x[rand]
    del(x[rand])
    return card

for i in range(200):
    card = Pickacard(cards)
    print(cards)
    cards.append(card)
T. Claverie
  • 11,380
  • 1
  • 17
  • 28
1

You're copying the reference, not the list data. Try the following options.

import copy
test = copy.copy(cards) 

OR

test = list(cards)  

Also, read about Deep and Shallow Copy

Community
  • 1
  • 1
Abdul Fatir
  • 6,159
  • 5
  • 31
  • 58
1

In Python, variable is just an alias of an object. so in your program, test and cards are two alias of the same object. So when you delete an item in cards, test changes too.

If you want test to be another object, you can use

test = cards[:]

This will build a new List that contains all the item of cards.

You can see more about how to copy a List here How to clone or copy a list in Python?

Community
  • 1
  • 1