Одиночное предложение удаления в цикле while удаляет два элемента - PullRequest
0 голосов
/ 08 ноября 2018

Я пишу простой секретный скрипт santa, который выбирает «GiftReceiver» и «GiftGiver» из списка. Создаются два списка и пустой фрейм данных:

import pandas as pd
import random

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

santaslist_givers = santaslist_receivers

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

Затем у меня есть цикл while, который выбирает случайные элементы из каждого списка, чтобы выбрать дарителя и получателя, а затем удаляет из соответствующего списка:

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)

Конечный кадр данных содержит только три элемента вместо шести:

print(finalDataframe)

1010 * возвращается *

    GiftGiver GiftReceiver
0    Dasher      Prancer
0     Comet        Vixen
0    Rudolf      Blitzen

Я вставил две строки печати в цикл while для расследования. Они распечатывают длину списка santaslist_receivers до и после удаления элемента. Ожидаемое возвращение - увидеть исходную длину списка на первом отпечатке, затем минус 1 на втором отпечатке, затем ту же длину снова на первом отпечатке следующей итерации цикла while, и так далее. В частности, я ожидаю:

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

Что возвращается

6,5,4,3,2,1

Что согласуется с тем, что DataFrame имеет только 3 строки, но я не вижу причины этого.

В чем заключается ошибка в моем коде или моем подходе?

Ответы [ 2 ]

0 голосов
/ 08 ноября 2018

Вы должны сделать явную копию вашего списка здесь

santaslist_givers = santaslist_receivers

Есть несколько вариантов сделать это, как объяснено в этот вопрос .

В этом случае я бы порекомендовал (если у вас Python> = 3.3):

santaslist_givers = santaslist_receivers.copy()

Если вы используете более старую версию Python, типичный способ сделать это:

santaslist_givers = santaslist_receivers[:]
0 голосов
/ 08 ноября 2018

Вы можете решить эту проблему, просто изменив эту строку

santaslist_givers = santaslist_receivers

до

 santaslist_givers = list(santaslist_receivers)

Переменные Python по сути являются указателями, поэтому они ссылаются на один и тот же список, то есть santaslist_givers и santaslist_receivers обращались к одному и тому же месту в памяти в вашей реализации. Чтобы сделать их разными, используйте функцию list

А для получения дополнительной информации вы можете обратиться copy.deepcopy

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...