队列类、出队和入队?Python

4

我有一个问题,它要求创建一个队列类,并编写方法dequeue和enqueue

以下是我目前的代码,请问有人能指点一下吗?

class queue:
      def __init__(self,queue):
            self.queue = []
      def dequeue(self):
            if len(queue) > 0:
                  e = queue[0]
                  queue = list[1:len(queue)]
            else:
                  return "There are no elements to remove"
      def enqueue(self,element):
            queue.insert([-1], element)

2
在引用该成员时,请使用 self.queue - 例如,e = queue[0] 应为 e = self.queue[0] - Tom
如果这是一个课程作业,这并不能帮助你,但如果你将来想使用队列数据结构,你几乎总是应该使用collections.deque而不是编写自己的代码。它是用C实现的(因此非常快),并经过多年的测试(因此不太可能遇到任何错误)。 - Blckknght
2个回答

10

这里有几个问题:

  • queue仅仅指代你的,并不是实例属性的同名变量 self.queue。你必须一直使用 self. ,最好给类和它的属性取不同的名称以避免混淆。(使用PEP 8风格来命名类, 把类名改为 Queue 也是有帮助的)
  • 当队列非空时,你计算出返回值 e,但你却从未使用 return 返回它;而是掉到函数结束后,自动返回None
  • list[1:len(queue)] 尝试对 list 类型进行切片,而不是你的实际列表 (self.queue)。你想要的是 self.queue[1:len(queue)]
  • 你可能不想在出错时返回字符串——因为字符串完全可以作为放入队列的一个有效对象——这正是异常的用途所在。
  • __init__ 接收了一个参数,但从未使用过。你可能想要使用这个参数作为队列内容的起始值,同时你也可能想将其设置成可选的。
  • list.insert 函数的第一个参数不应该是一个类似于 [-1] 的列表,而应该是索引,如 -1
  • 如果这是 Python 2.x,则不应创建经典类; 如果没有其他要继承的内容,则继承自 `object`。
  • 看起来你可能混合了制表符和空格进行缩进,不要这样做。

此外,有一些事情可以更简单:

  • 如果你想切片到列表的末尾,只需要省略结尾即可,例如使用 self.queue[1:],而不是使用 len(self.queue)
  • 为了更简单地从列表左侧获取并移除一个值,可以使用 pop(0)
  • 要在列表的右侧添加一个值,可以使用append
  • 要检查一个列表是否非空,只需执行 if the_list,而不是 if len(the_list) > 0。空集合总是falsey,非空集合为true。
  • 但实际上你根本不需要进行检查——如果列表为空,pop 将会引发一个异常,这正是你想要的。

所以:

class Queue(object):
    def __init__(self, queue=None):
        if queue is None:
            self.queue = []
        else:
            self.queue = list(queue)
    def dequeue(self):
        return self.queue.pop(0)
    def enqueue(self, element):
        self.queue.append(element)

如果您想要自定义异常消息,例如将IndexError: pop from empty list更改为IndexError: dequeue from empty Queue,您可以使用try语句实现:

    def dequeue(self):
        try:
            return self.queue.pop(0)
        except IndexError:
            raise IndexError('dequeue from empty Queue') 
如果你想要测试你的队列类是否正常工作,需要编写测试函数并调用它们。例如:
def test_queue():
    q = Queue()
    for i in range(10):
        q.enqueue(i)
    for i in range(10):
        value = q.dequeue()
        if value != i:
            print('Value #{} should be {} but is {}'.format(i, i, value))
    try:
        value = q.dequeue()
    except IndexError:
        pass # we _want_ an error here
    else:
        print('#10 should raise an IndexError, but got {}'.format(value))

if __name__ == '__main__':
    test_queue()

现在您只需将该文件作为脚本运行即可运行您的测试。

在实际情况中,您需要考虑更完整的测试,覆盖所有您能想到的奇怪边缘情况。您可能还需要使用unittest库或像nose这样的第三方解决方案来组织和简化您的测试。


好的,谢谢您的回答,非常有帮助。那我该如何运行它呢? - user2928929
1
@user2928929:嗯,你需要编写一些使用队列的函数,并调用该函数。我可以在答案中添加一个示例。 - abarnert

0
请使用self.queue,否则会出现错误。
当self.queue不为空时,请确保返回元素。
当队列为空时,最好不要返回消息,而是应该引发异常。
class Queue:
    def __init__(self,queue):
        self.queue = []
    def dequeue(self):
        return self.queue.pop(0)
    def enqueue(self,element):
        self.queue.append(element)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接