Python ValueError:list.remove(x):x不在列表中(但它是!)

Python ValueError:list.remove(x):x不在列表中(但它是!),python,python-2.7,Python,Python 2.7,我正在阅读O'Reilly的书《用R和Ruby探索日常生活》,并试图用Python重写所有Ruby代码。第一个例子是一个计算建筑物需要多少浴室的模型。下面是我正在使用的代码 但是,当我运行example34.py文件时,出现以下错误: Traceback (most recent call last): File "<stdin>", line 1, in <module> File "example34.py", line 39, in <module&g

我正在阅读O'Reilly的书《用R和Ruby探索日常生活》,并试图用Python重写所有Ruby代码。第一个例子是一个计算建筑物需要多少浴室的模型。下面是我正在使用的代码

但是,当我运行example34.py文件时,出现以下错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "example34.py", line 39, in <module>
    new_restroom.enter(queue.pop(0))
  File "restroom.py", line 21, in enter
    unoccupied_facilities[0].occupy(person)
  File "restroom.py", line 46, in occupy
    Person.population.remove(person)
ValueError: list.remove(x): x not in list
restroom.py:

from random import randint
duration = 9 * 60  # minutes


class Restroom(object):

    def __init__(self, facilities_per_restroom=3):
        # Start with an empty queue
        self.queue = []
        # The facilities in this restroom
        self.facilities = []
        # Creates the facilities
        self.facilities = ([Facility() for each in
                            range(facilities_per_restroom)])

    def enter(self, person):
        unoccupied_facilities = [
            facility for facility in self.facilities
            if facility.occupied() == 0]
        if unoccupied_facilities:
            unoccupied_facilities[0].occupy(person)
        else:
            self.queue.append(person)
            Person.population.remove(person)

    def tick(self):
        [each.tick() for each in self.facilities]
        [f.tick for f in self.facilities]


class Facility(object):
    def __init__(self):
        self.occupier = None  # no one is occupying this facility at the start
        self.duration = 0  # how long the facility has been occupied

    def occupied(self):
        return 1 if (self.occupier is not None) else 0

    def occupy(self, person):
        # if the facility is unoccupied, add the person. Else, return false.
        if not self.occupied():
            self.occupier = person
            self.duration = 1
            #remove the person from the population since
            # they're in a facility now
            Person.population.remove(person)
            return 1  # return true
        else:
            return 0  # Return false

    def vacate(self):
        Person.population.append(self.occupier)
        self.occupier = None

    def tick(self):
        # if the facility is occupied and they've been
        # there longer than the use duration, have them leave
        if self.occupied() and (self.duration > self.occupier.use_duration):
            self.vacate()
            self.duration = 0
        elif self.occupied():
            # If occupied, increment the time
            self.duration += 1


class Person(object):

    #Class variable for storing the entire population
    population = []

    def __init__(self, frequency=4, use_duration=1):
        # Number of times a person uses the facilities per day
        self.frequency = frequency
        # How long each person uses the facilities
        self.use_duration = use_duration

    def need_to_go(self):

        return randint(1, duration) <= self.frequency
来自随机导入randint
持续时间=9*60分钟
班级休息室(对象):
定义初始值(自身,每个卫生间的设施=3):
#从一个空队列开始
self.queue=[]
#这个洗手间的设施
self.facilities=[]
#创建设施
self.Facility=([Facility())适用于每个项目
范围(每个卫生间的设施)
def enter(自我、个人):
未占用的设施=[
自助设施中的设施对设施
如果设施被占用()==0]
如果设施无人占用:
未占用的设施[0]。占用(人)
其他:
self.queue.append(个人)
人。人口。移除(人)
def勾选(自我):
[each.tick()表示自助设施中的每个项目]
[f.在自助设施中勾选f]
类别设施(对象):
定义初始化(自):
自住者=无#一开始没有人占用该设施
self.duration=0#设施被占用的时间
def占用(自身):
如果(自住者不是无)其他0,则返回1
定义(自我、个人):
#如果设施未被占用,请添加人员。否则,返回false。
如果不是自占用():
自住者
self.duration=1
#将此人从人口中删除,因为
#他们现在在一个设施里
人。人口。移除(人)
返回1#返回true
其他:
返回0#返回false
def空出(自我):
个人.人口.附加(自住者)
自住者=无
def勾选(自我):
#如果设施被占用并且他们已经
#如果超过使用期限,请让他们离开
如果self.occulation()和(self.duration>self.occulator.use_duration):
腾空
self.duration=0
elif self.occubled():
#如果被占用,则增加时间
self.duration+=1
类人(对象):
#用于存储整个总体的类变量
人口=[]
定义初始(自我,频率=4,使用持续时间=1):
#一个人每天使用设施的次数
self.frequency=频率
#每个人使用这些设施的时间有多长
self.use\u duration=使用\u duration
def需要执行(自我):

返回randint(1,duration),但只需查看stacktrace,它就会清楚地表明
ValueError:list.remove(x):x不在列表中
。您试图删除的
人员不在列表中。因此,您需要捕获此异常并适当地处理它-

#some loop, get the person to be removed
...
try:
    Person.population.remove(person)
except ValueError:
    pass #silently continue. Either that person is already removed or is not present.
...

当然,这段代码并不完整。它只是强调了
try:except ValueError:
用法的用法

您在代码中遇到了一个简单的错误

休息室有一个队列,其中添加了没有可用隔间的Person对象

逻辑是:

def enter(self, person):
    unoccupied_facilities = [
        facility for facility in self.facilities
        if facility.occupied() == 0]
    if unoccupied_facilities:
        unoccupied_facilities[0].occupy(person)
    else:
        self.queue.append(person)
        Person.population.remove(person)
请注意,
.occulation()
人员.人口
列表中删除人员,或者如果没有可用的暂停,则该人员将被添加到
自.queue
,并从
人员.人口
中删除

example34
代码随后处理该队列:

queue = list(new_restroom.queue)
# Clear the queue to prepare for sorting
new_restroom.queue = []
# Take each person from the temporary queue and try adding
# them a facility
while bool(queue):
    # De-queue the person at the front of the line, place in an
    # unoccupied facility or, if none, back to the restroom queue
    new_restroom.enter(queue.pop(0))
因此,人们被从队列中带走,重新进入洗手间。如果任何一个摊位是空的,
未占用的设施[0]。占用(个人)
尝试将该人从
个人中删除。人口
再次。在这一点上提出了一个例外,因为这个人肯定不在这个列表中了

解决方案是不从两个不同位置的人群中删除
人员
,或者在处理队列时将该人员重新添加回人群中

将队列处理代码更改为:

while bool(queue):
    # De-queue the person at the front of the line, place in an
    # unoccupied facility or, if none, back to the restroom queue
    person = queue.pop(0)
    Person.population.append(person)
    new_restroom.enter(person)
修复了该问题,例如:

$ python2.7 example34.py 
{100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0]}

没有看到代码的其余部分。有环路吗?您是否总是在删除前测试列表中是否有
人员
?在什么情况下会提出例外?仅仅通过运行代码?或者你给了它某些输入,调整了代码,等等?是的,我们可以跟踪到github的链接,但是谁能说代码在几周后会是一样的呢?或者根本就在那里?让你的问题独立起来,而不需要外部链接在问题的剩余生命周期内继续工作。ExamPle34.py中包含输入,但每次运行时都会引发异常。具体地说,“设施”没有被填满/腾空的问题,但只要浴室队列中有一个人,事情就会破裂。浴室或
洗手间
?添加了上面的代码(起初在GitHub上链接到它会更容易)。@Brideau,因为我现在看到了完整的代码。只需将
try:except:
块放入上面描述的代码。如果要以静默方式继续,请使用
pass
。这应该可以为您解决问题…我知道,
try:except:
块是用于调试的,但并没有真正解决根本问题,对吗?我只是尝试将
try:except:
块添加到使用Person.population.remove(Person)的两个位置,但奇怪的是结果仍然相同。与上述错误消息完全相同。不知怎的,它打破了那个块…@Brideau问题是,由于您试图从列表中删除一个不存在的对象,所以引发了这个异常。因为它不在那里,所以它抛出了一个异常。那又怎么样
$ python2.7 example34.py 
{100: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0]}