Single remove clause in while loop is removing two elements











up vote
0
down vote

favorite












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?










share|improve this question






















  • Mandatory reading: nedbatchelder.com/text/names.html
    – bruno desthuilliers
    Nov 8 at 12:29















up vote
0
down vote

favorite












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?










share|improve this question






















  • Mandatory reading: nedbatchelder.com/text/names.html
    – bruno desthuilliers
    Nov 8 at 12:29













up vote
0
down vote

favorite









up vote
0
down vote

favorite











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?










share|improve this question













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?







python while-loop






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 8 at 11:21









branches

257420




257420












  • Mandatory reading: nedbatchelder.com/text/names.html
    – bruno desthuilliers
    Nov 8 at 12:29


















  • Mandatory reading: nedbatchelder.com/text/names.html
    – bruno desthuilliers
    Nov 8 at 12:29
















Mandatory reading: nedbatchelder.com/text/names.html
– bruno desthuilliers
Nov 8 at 12:29




Mandatory reading: nedbatchelder.com/text/names.html
– bruno desthuilliers
Nov 8 at 12:29












2 Answers
2






active

oldest

votes

















up vote
2
down vote



accepted










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






share|improve this answer






























    up vote
    0
    down vote













    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[:]





    share|improve this answer





















      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














       

      draft saved


      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206736%2fsingle-remove-clause-in-while-loop-is-removing-two-elements%23new-answer', 'question_page');
      }
      );

      Post as a guest
































      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      2
      down vote



      accepted










      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






      share|improve this answer



























        up vote
        2
        down vote



        accepted










        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






        share|improve this answer

























          up vote
          2
          down vote



          accepted







          up vote
          2
          down vote



          accepted






          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






          share|improve this answer














          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







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 8 at 11:54

























          answered Nov 8 at 11:48









          Albin Paul

          1,220517




          1,220517
























              up vote
              0
              down vote













              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[:]





              share|improve this answer

























                up vote
                0
                down vote













                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[:]





                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  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[:]





                  share|improve this answer












                  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[:]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 8 at 11:55









                  Pumpkin

                  466




                  466






























                       

                      draft saved


                      draft discarded



















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206736%2fsingle-remove-clause-in-while-loop-is-removing-two-elements%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest




















































































                      Popular posts from this blog

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)