Python列表不在/在问题中

时间:2014-11-18 22:11:28

标签: python

我正在构建一个简单的" 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']

尽管我对条纹问题的回答是否定的,但即使斑马列在条纹列表中,斑马仍然在那里,如果它在条纹列表中,它应该从答案中删除。

谢谢!

4 个答案:

答案 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)