'My class object is deleting part of it's contents

I apologize for the non-descriptive title, I do not know how else to describe the issue.

Here is my current code:

from __future__ import annotations
import random

class Hat():
    def __init__(self, **kw):
        self.contents = []
        keys = list(kw.keys())
        values = list(kw.values())
        j = 0
        while j < len(values):
            h = 0
            while h < values[j]:
                self.contents.append(keys[j])
                h += 1
            j += 1
        
    def draw(self, num_balls = 0):
        j = 0
        picked_balls = []
        not_picked_balls = self.contents
        while j < num_balls:
            if len(not_picked_balls) == 0:
                break
            pick = random.randint(0, (len(not_picked_balls) - 1))
            picked_balls.append(not_picked_balls[pick])
            not_picked_balls.pop(pick)
            j += 1
        return(picked_balls)

It is very messy I know... I will do a little bit of explaining. The class has to be initialized in this form:

hat1 = Hat(yellow=10, red=8)

I figured the best way to do this was a dictionary using **kw, hence my initialization. I then turn it into a list called self.contents.

That is not the issue, however, that is in the draw function. I made it so that it would not change the self.contents list, but somehow it is changing it. (hat.draw just returns a list of randomly chosen colored "balls" from the "Hat") This is what I am doing:

print(hat1.draw(8))
print(hat1.draw(8))
print(hat1.draw(8))
print(hat1.draw(8))
print(hat1.draw(8))

And this is the output:

['yellow', 'yellow', 'red', 'yellow', 'red', 'red', 'yellow', 'yellow']
['red', 'red', 'yellow', 'yellow', 'yellow', 'yellow', 'red', 'yellow']
['red', 'red']
[]
[]

As you can see with the output, somehow I seem to be losing contents. That is shown true when I put a print(self.contents) in the function to find the error, this is what I get:

['yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'red', 'red', 'red', 'red', 'red', 'red', 'red', 'red']
['yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'yellow', 'red', 'red', 'red']
['yellow', 'yellow']
[]
[]

I cannot seem to find why this would be changing. Any help is appreciated!



Solution 1:[1]

This is the cause of the error:

not_picked_balls = self.contents

In python, this means that both not_picked_balls and self.contents reference the same memory location

Instead, you need to make a copy of self.contents and assign it to not_picked_balls

not_picked_balls = self.contents.copy()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1