我正在尝试在Python 3.3中创建一个简单的程序,该程序获取四个名称的列表,并随机将它们分配给列表中的另一个人。例如,如果名字是John,Aaron,Lydia和Robin:
约翰先走,然后选择一个名字。他无法画出自己的;如果他这样做,他会把它放回去并再次吸引。说约翰画了罗宾的名字。罗宾的名字将从游泳池中消失。接下来是亚伦轮到画画了。他画了约翰。约翰的名字被淘汰了。等,直到所有的名字都被分配。
我创建了一个包含四个名称的列表,并为每个名称分配了值1-4。但是,从列表中删除时,我遇到了一个问题,说该值不存在。
list.remove(x):x不在列表中。
它看起来像这样:
def drawNames():
import random
John=1
Aaron=2
Lydia=3
Robin=4
validNames=[John, Aaron, Lydia, Robin]
nameDrawn=random.choice(validNames)
def draw():
nameDrawn=random.choice(validNames)
#John's Draw:
draw()
if nameDrawn != 1:
if nameDrawn == 2:
print("John drew: Aaron")
validNames.remove(2)
elif nameDrawn == 3:
print("John drew: Lydia")
validNames.remove(3)
elif nameDrawn == 4:
print("John drew: Robin")
validNames.remove(4)
#Aaron's Draw:
draw()
if nameDrawn !=2:
if nameDrawn ==1:
print("Aaron drew: John")
validNames.remove(1)
elif nameDrawn ==3:
print("Aaron drew: Lydia")
validNames.remove(3)
elif nameDrawn ==4:
print("Aaron drew: Robin")
validNames.remove(4)
#Lydia's Draw:
draw()
if nameDrawn !=3:
if nameDrawn ==1:
print("Lydia drew: John")
validNames.remove(1)
elif nameDrawn ==2:
print("Lydia drew: Aaron")
validNames.remove(2)
elif nameDrawn ==4:
print("Lydia drew: Robin")
validNames.remove(4)
#Robin's Draw:
draw()
if nameDrawn !=4:
if nameDrawn ==1:
print("Robin drew: John")
validNames.remove(1)
elif nameDrawn ==2:
print("Robin drew: Aaron")
validNames.remove(2)
elif nameDrawn ==3:
print("Robin drew: Lydia")
validNames.remove(3)
drawNames()
我也尝试使用名称而不是数值,这会产生相同的错误。
我也觉得这是一个效率低下的计划。如果你有更好的建议,我会非常感激。
答案 0 :(得分:2)
使用下面的代码可能会有更好的里程数;它比你上面提供的名称更容易扩展。
import copy
import random
validNames=["John", "Aaron", "Lydia", "Robin"]
def drawNames(namelist,currentname):
'''
namelist: list of names to draw from
currentname: name of person doing the current draw
'''
draw_namelist = copy.copy(namelist) # make a copy to remove person drawing if needed
if currentname in draw_namelist: # check if the person drawing is in the list
draw_namelist.remove(currentname) # remove current name if in list
try:
drawn_name = random.choice(draw_namelist)
namelist.remove(drawn_name)
newnamelist = namelist
print "Drew {}".format(drawn_name)
print "New list: {}".format(newnamelist)
except:
print "Nobody for me to draw!"
drawn_name=None
newnamelist = namelist
return drawn_name, newnamelist
然后可以按如下方式工作:
In [39]: newlist=["John", "Aaron", "Lydia", "Robin"]
In [40]: name,newlist = drawNames(newlist,"Lydia")
Drew Robin
New list: ['John', 'Aaron', 'Lydia']
In [41]: name,newlist = drawNames(newlist,"John")
Drew Aaron
New list: ['John', 'Lydia']
In [42]: name,newlist = drawNames(newlist,"Aaron")
Drew John
New list: ['Lydia']
In [43]: name,newlist = drawNames(newlist,"Robin")
Drew Lydia
New list: []
答案 1 :(得分:1)
您必须调用实际元素,而不是删除索引。将数字替换为列表中存在的人的实际名称,代码应按预期工作。
答案 2 :(得分:0)
请注意,如果列表len为奇数
,则存在潜在的无限循环import random
from copy import copy
def f(name):
x = random.choice(validNames)
while x == name:
x = random.choice(validNames)
else:
validNames.remove(x)
return (name, x)
print map(f, copy(validNames))
>>> [('John', 'Robin'), ('Aaron', 'John'), ('Lydia', 'Aaron'), ('Robin', 'Lydia')]
答案 3 :(得分:0)
最简单的方法是将名称随机分配并将每个名称分配给下一个名称。它还保证两个人不会互相拥有名字。
>>> from random import shuffle
>>> names=['John', 'Aaron', 'Lydia', 'Robin']
>>> shuffle(names)
>>> dict(zip(names, names[-1:] + names))
{'Aaron': 'Lydia', 'John': 'Robin', 'Lydia': 'John', 'Robin': 'Aaron'}
答案 4 :(得分:0)
你肯定是这么做的。
不要反复搜索列表并删除值,只需将列表随机播放并读取对,如下所示:
from random import shuffle
def random_pairs(lst):
shuffle(lst)
return zip(lst[::2], lst[1::2])
def main():
names = 'John,Aaron,Lydia,Robin'.split(',')
print random_pairs(names)
if __name__=="__main__":
main()
答案 5 :(得分:0)
>>> from random import shuffle
>>> valid_names=["John", "Aaron", "Lydia", "Robin"]
>>> shuffle(valid_names)
>>> for pair in zip(valid_names, (valid_names*2)[1:]):
... print(pair)
...
('Aaron', 'John')
('John', 'Lydia')
('Lydia', 'Robin')
('Robin', 'Aaron')