【问题标题】:Python - list.remove(x) x not in listPython - list.remove(x) x 不在列表中
【发布时间】:2013-12-07 02:15:34
【问题描述】:

我正在尝试在 Python 3.3 中创建一个简单的程序,该程序采用四个名称的列表,并将它们随机分配给列表中的另一个人。例如,如果名字是 John、Aaron、Lydia 和 Robin:

约翰首先选择了一个名字。他不能自己画;如果他这样做了,他就把它放回去,然后再画一次。假设约翰画了罗宾的名字。罗宾的名字将从池中删除。接下来轮到Aaron画了。他画约翰。约翰的名字被删除了。等等,直到所有名称都被分配。

我创建了一个包含四个名称的列表,并为每个名称分配了一个值 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()

我也尝试过使用名称而不是数值,这产生了同样的错误。

我也觉得这是一个低效的方案。如果您有更好的建议,我将不胜感激。

【问题讨论】:

  • 这是像“白象”还是“秘密圣诞老人”的图画?你想防止两个人互相挑剔吗?

标签: python list python-3.x scripting


【解决方案1】:

使用下面这样的代码,您可能会获得更好的里程;它比您上面提供的名称更具可扩展性。

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: []

【讨论】:

  • 这样的效率要高得多。我会试试的。
  • 我如何为不画自己名字的人创建这个帐户?我试图在 if 语句中添加一些东西。我在定义之前将您的 random.choice 更改为进一步向上并说 nameChoice=random.choice(namelist) 然后在您的 if 语句中添加 if currentname in namelist 和 currentname!=nameChoice: 但我给出了无效的语法。
  • 嗨对不起,我最初错过了!我已经更新了我的答案,它应该可以工作并且更强大:)
  • 谢谢!将其更改为 Python 3.3 后,它的效果非常好!效率更高。
【解决方案2】:

您必须调用实际元素,而不是 remove 中的索引。将数字替换为列表中存在的人的实际姓名,代码应按预期工作。

【讨论】:

  • 感谢您的回复。但正如我试图在问题中陈述的那样,当我执行“validNames.remove(Robin)”之类的操作时,它仍然会引发“x not in list”错误。
  • 哦,我错过了,对不起。
【解决方案3】:

请注意,如果列表 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')]

【讨论】:

    【解决方案4】:

    你肯定在努力。

    与其反复寻找列表并删除值,不如将列表打乱并读出对,如下所示:

    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】:
    >>> 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')
    

    【讨论】:

      【解决方案6】:

      最简单的方法是将名称洗牌并将每个名称分配给下一个。它还保证两个人不会有彼此的名字。

      >>> 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'}
      

      【讨论】:

        猜你喜欢
        • 2022-12-17
        • 2018-07-05
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        • 2019-03-15
        • 1970-01-01
        • 2021-01-21
        • 2014-08-14
        相关资源
        最近更新 更多