0

I am writing a simple secret santa script that selects a "GiftReceiver" and a "GiftGiver" from a list. Two lists and an empty dataframe to be populated are produced:

import pandas as pd
import random

santaslist_receivers = ['Rudolf',
        'Blitzen',
        'Prancer',
        'Dasher',
        'Vixen',
        'Comet'
        ]

santaslist_givers = santaslist_receivers

finalDataFrame = pd.DataFrame(columns = ['GiftGiver','GiftReceiver'])

I then have a while loop that selects random elements from each list to pick a gift giver and receiver, then remove from the respective list:

while len(santaslist_receivers) > 0:

    print (len(santaslist_receivers)) #Used for testing.

    gift_receiver = random.choice(santaslist_receivers)
    santaslist_receivers.remove(gift_receiver)

    print (len(santaslist_receivers)) #Used for testing.

    gift_giver = random.choice(santaslist_givers)
    while gift_giver == gift_receiver:                      #While loop ensures that gift_giver != gift_receiver
        gift_giver = random.choice(santaslist_givers)

    santaslist_givers.remove(gift_giver)

    dummyDF = pd.DataFrame({'GiftGiver':gift_giver,'GiftReceiver':gift_receiver}, index = [0])

    finalDataFrame = finalDataFrame.append(dummyDF)

The final dataframe only contains three elements instead of six:

print(finalDataframe)

returns

    GiftGiver GiftReceiver
0    Dasher      Prancer
0     Comet        Vixen
0    Rudolf      Blitzen

I have inserted two print lines within the while loop to investigate. These print the length of the list santaslist_receivers before and after the removal of an element. The expected return is to see original list length on the first print, then minus 1 on the second print, then the same length again on the first print of the next iteration of the while loop, then so on. Specifically I expect:

6,5,5,4,4,3,3... and so on.

What is returned is

6,5,4,3,2,1

Which is consistent with the DataFrame having only 3 rows, but I do not see the cause of this.

What is the error in my code or my approach?

acolls_badger
  • 423
  • 1
  • 9
  • 29

2 Answers2

2

You can solve it by simply changing this line

santaslist_givers = santaslist_receivers

to

 santaslist_givers = list(santaslist_receivers)

Python variables are pointers essentially so they refer to the same list , ie santaslist_givers and santaslist_receivers were accessing the same location in memory in your implementation . To make them different use a list function

And for some extra information , you can refer copy.deepcopy

Albin Paul
  • 3,330
  • 2
  • 14
  • 30
0

You should make an explicit copy of your list here

santaslist_givers = santaslist_receivers

there are multiple options for doing this as explained in this question.

In this case I would recommend (if you have Python >= 3.3):

santaslist_givers = santaslist_receivers.copy()

If you are on an older version of Python, the typical way to do it is:

santaslist_givers = santaslist_receivers[:]
Pumpkin
  • 233
  • 1
  • 9