while 循环中的单个删除子句正在删除两个元素
Posted
技术标签:
【中文标题】while 循环中的单个删除子句正在删除两个元素【英文标题】:Single remove clause in while loop is removing two elements 【发布时间】:2018-11-08 11:21:41 【问题描述】:我正在编写一个简单的秘密圣诞老人脚本,它从列表中选择一个“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)
返回
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
这与只有 3 行的 DataFrame 一致,但我看不出这是什么原因。
我的代码或方法有什么错误?
【问题讨论】:
必读:nedbatchelder.com/text/names.html 【参考方案1】:只需更改此行即可解决
santaslist_givers = santaslist_receivers
到
santaslist_givers = list(santaslist_receivers)
Python 变量本质上是指针,因此它们引用同一个列表,即santaslist_givers
和santaslist_receivers
在您的实现中访问内存中的相同位置。要使它们不同,请使用list
函数
还有一些额外的信息,你可以参考copy.deepcopy
【讨论】:
【参考方案2】:您应该在此处明确复制您的列表
santaslist_givers = santaslist_receivers
如this question 中所述,有多种选择。
在这种情况下,我建议(如果您的 Python >= 3.3):
santaslist_givers = santaslist_receivers.copy()
如果您使用的是旧版本的 Python,典型的做法是:
santaslist_givers = santaslist_receivers[:]
【讨论】:
以上是关于while 循环中的单个删除子句正在删除两个元素的主要内容,如果未能解决你的问题,请参考以下文章
当只剩下一个节点时,循环链表中的删除函数将next和previous更改为null