我正在构建一个简单的" 20问题游戏"在Python中,但列表有些困难。
这是我目前的代码:
answer = []
animals = ['lion', 'tiger', 'human', 'zebra', 'horse', 'goat', 'bee', 'snake', 'narwhal']
legs = ['lion', 'tiger', 'zebra', 'horse', 'goat', 'bee']
stripes = ['tiger', 'zebra', 'bee', 'snake']
hooves = ['goat', 'horse']
horn = ['narwhal']
tail = ['lion', 'tiger', 'zebra', 'horse', 'goat']
legsq = input("Does it have more than 2 legs? ")
if(legsq.lower()=='yes'):
for animal in legs:
answer.append(animal)
else:
for animal in animals:
if animal not in legs:
answer.append(animal)
print(answer)
stripesq = input("Does it have stripes? ")
if(stripesq.lower()=='yes'):
for animal in answer:
if animal not in stripes:
answer.remove(animal)
else:
for animal in answer:
if animal in stripes:
answer.remove(animal)
print(answer)
问题在于,当我运行它时,一切正常,除了第二个问题后,有些动物在answer[]
时不应该出现。
这是我得到的输出:
>>>
Does it have more than 2 legs? yes
['lion', 'tiger', 'zebra', 'horse', 'goat', 'bee']
Does it have stripes? no
['lion', 'zebra', 'horse', 'goat']
尽管我对条纹问题的回答是否定的,但即使斑马列在条纹列表中,斑马仍然在那里,如果它在条纹列表中,它应该从答案中删除。
谢谢!
答案 0 :(得分:4)
如果在迭代时修改列表,它将无法按预期工作,因此不起作用:
for animal in answer: # Iteration over answer.
if animal in stripes:
answer.remove(animal) # Modification of answer.
以下是修复方法:
i = 0
while i < len(answer):
if answer[i] in stripes:
del answer[i]
else:
i += 1
根据martineau的建议,此解决方案也有效,因为answer[:]
制作了answer
的副本:
for animal in answer[:]:
if animal in stripes:
answer.remove(animal)
(我同意abamert。)即使它在这里正常工作,我个人也建议不要在循环中使用list.remove
,因为list.remove
会查找匹配的值列表的开头,在某些用例中,这会删除错误的,意外的元素。如果不确定,最好远离这种模式(迭代+删除)。
请注意,如果answer
非常长并且太多,则上述不正确和正确的解决方案都会不必要地缓慢(O(n 2 )而不是O(n))要删除的项目。要在这种情况下加快速度,请创建一个新列表:
answer = [animal for animal in answer if animal in stripes]
如果stripes
也很长,您可以通过先将stripes
转换为set
来加快速度:
stripes_set = set(stripes)
answer = [animal for animal in answer if animal in stripes_set]
答案 1 :(得分:3)
使用正确的数据结构通常会使事情变得更快,如pts's great answer explains。但它也经常使事情更简单。
例如,如果您有两个集合,则可以使用简单的运算符简洁,可读和高效来计算交集,并集,集合差异等。而且,因为套装本质上并不关心重复值,整个“在我们删除它之前确保它存在”或“在我们添加它之前确保它不在那里”你遇到的问题没有问题t首先存在:
answer = set()
animals = {'lion', 'tiger', 'human', 'zebra', 'horse', 'goat', 'bee', 'snake', 'narwhal'}
legs = {'lion', 'tiger', 'zebra', 'horse', 'goat', 'bee'}
stripes = {'tiger', 'zebra', 'bee', 'snake'}
hooves = {'goat', 'horse'}
horn = {'narwhal'}
tail = {'lion', 'tiger', 'zebra', 'horse', 'goat'}
legsq = input("Does it have more than 2 legs? ")
if(legsq.lower()=='yes'):
answer |= legs
else:
answer -= legs
print(answer)
......等等。
答案 2 :(得分:0)
使用过滤功能或列表推导来做你想做的事情会更有意义。
answer = []
animals = ['lion', 'tiger', 'human', 'zebra', 'horse', 'goat', 'bee', 'snake', 'narwhal']
legs = ['lion', 'tiger', 'zebra', 'horse', 'goat', 'bee']
stripes = ['tiger', 'zebra', 'bee', 'snake']
hooves = ['goat', 'horse']
horn = ['narwhal']
tail = ['lion', 'tiger', 'zebra', 'horse', 'goat']
legsq = input("Does it have more than 2 legs? ")
if(legsq.lower()=='yes'):
answer = [i for i in legs]
else:
answer = [i for i in animals if i not in legs]
print(answer)
让语言为你做迭代。
答案 3 :(得分:0)
迭代列表时不要编辑列表。 检查动物是否仍然存在于答案中。 然后,如果条带列表中不存在该动物,则将其删除。
if(stripesq.lower()=='yes'):
for animal in animals:
if animal in answer:
if animal not in stripes:
answer.remove(animal)
else:
for animal in stripes:
answer.remove(animal)