【问题标题】:Extracting from a queue in python从python中的队列中提取
【发布时间】:2018-01-28 01:19:35
【问题描述】:

我在尝试从队列中提取元素直到给定数字时遇到问题。如果给定的号码没有排队,代码应该让队列为空并给出一条消息。

相反,我收到此错误消息,但我无法解决它:

Traceback (most recent call last):
  File "python", line 45, in <module>
IndexError: list index out of range

这是我当前的代码:

class Queue():
  def __init__(self):
      self.items = []
  def empty(self):
    if self.items == []:
      return True
    else:
      return False
  def insert(self, value):
        self.items.append(value)
  def extract(self):
    try:
      return self.items.pop(0)
    except:
      raise ValueError("Empty queue")
  def last(self):
    if self.empty():
      return None
    else:
      return self.items[0]

import random
def randomlist(n2,a2,b2):
    list = [0]  * n2
    for i in range(n2):
      list[i] = random.randint(a2,b2)
    return list

queue1=Queue()
for i in range (0,10):
  queue1.insert(randomlist(10,1,70)[i])
if queue1.empty()==False :
  print("These are the numbers of your queue:\n",queue1.items)

test1=True
while test1==True:
  s=(input("Input a number:\n"))
  if s.isdigit()==True :
   test1=False
   s2=int(s)
  else:
    print("Wrong, try again\n")

for i in range (0,10) :    
  if queue1.items[i]!=s2 :
    queue1.extract()
  elif queue1.items[i]==s2 :
    queue1.extract()
    print ("Remaining numbers:\n",queue1.items)
    break
if queue1.empty()==True :
  print ("Queue is empty now", cola1.items)

【问题讨论】:

  • 让我解释一下自己...想象一下这个例子 这些是你的队列的数字:[30, 7, 19, 62, 41, 1, 3, 35, 16, 46] 输入一个数字: 7 所以结果应该是: 剩余数:[19, 62, 41, 1, 3, 35, 16, 46]
  • 你的def randomlist(n2,a2,b2)list(random.choices(range(a2,b2+1),k=n2)
  • 您不应该使用listdict 或任何其他保留字作为变量名 - 您的变量会隐藏内置类型,您会遇到问题。

标签: python queue


【解决方案1】:

从队列中提取元素直到给定数量。如果给定的号码没有排队,代码应该让队列为空并给出一条消息。

while not queue.empty():
    if queue.extract() == target:
        print('Found! Remaining numbers:', queue.items)
        break
else:
    print('Not found! Remaining numbers:', queue.items)

【讨论】:

    【解决方案2】:

    在浏览列表时修改列表是个坏主意。

     for i in range (0,10) :    
        if queue1.items[i]!=s2 :
            queue1.extract()
        elif queue1.items[i]==s2 :
            queue1.extract()
            print ("Remaining numbers:\n",queue1.items)
    

    此代码修改您的队列 - 项目,它缩短了项目列表,但如果没有找到项目,您仍然会遍历整个范围。所以你的内部列表会越来越短,你的范围 (i) 会向 i 前进。

    当您访问不再在队列中的items[i] 时。

    解决方案(编辑感谢Stefan Pochmann's 评论):

     for _ in range(len(queue1.items)):    # no hardcoded length anymore
        item = queue1.extract()              # pop item
        if item == s2 :                      # check item for break criteria
            print ("Remaining numbers:\n",queue1.items)
            break
    

    【讨论】:

    • @StefanPochmann 我只是在重用他的 Queue 类。他正在丢弃队列中的值,直到找到数字,丢弃找到的数字并打印剩余的数字。看了之后才发现你说的,谢谢指出。不过,使用 range() 我仍然感觉更好,因为我正在修改内部项目列表并且使用 for _ in queue1.items: 这样对我来说看起来很危险
    • 哈,不想再等了,发布了我的答案并打算删除我的 cmets,但几秒钟后你更新了:-)。哦,好吧,我们还是有点不同。
    • 对,我认为理想情况下我们根本不应该从外部直接使用队列的内部items。这就是我在那个范围内更喜欢“而不是空”的原因之一。我还在触摸items,但我想这只是为了调试打印以检查一切是否正常。无论如何,我想说你的更新版本有了很大的改进,你解释了他们的失败(我只是懒得再解释一次),所以 +1 也是 :-)
    【解决方案3】:

    您可以尝试替换代码的最后一部分,即

    for i in range (0,10) :    
      if queue1.items[i]!=s2 :
        queue1.extract()
      elif queue1.items[i]==s2 :
        queue1.extract()
        print ("Remaining numbers:\n",queue1.items)
        break
    if queue1.empty()==True :
      print ("Queue is empty now", cola1.items)
    

    poptill = -1 # index till where we should pop
    for i in range(0,len(queue1.items)): # this loop finds the index to pop queue till
      if queue1.items[i]==s2:
        poptill = i
        break
    
    if poptill != -1: # if item to pop was found in queue
      i = 0
      while i <= poptill: # this loop empties the queue till that index
        queue1.extract()
        i += 1
      if queue1.empty()==True :
        print ("Queue is empty now", queue1.items)
      else:
        print ("Remaining numbers:\n",queue1.items)
    else: # else item was not found in list
      for i in range(0,len(queue1.items)): # this loop empties the queue
        queue1.extract()
      print ("no item found, so emptied the list, numbers:\n",queue1.items)
    

    在这里,我们找到索引位置直到我们应该在第一个循环中弹出的位置,然后在第二个循环中弹出队列直到该索引,最后如果在列表中找不到要弹出的项目,我们在第三个循环中清空列表.

    【讨论】:

    • 非常感谢,法拉兹。无论如何,如果给定的数字不在队列中,代码不会提取任何项目,我该如何解决?
    • 我编辑了,如果没有找到任何项目来清空列表,您可以编写代码来清空队列类中的列表并在 final else 中调用它,或者编写代码在 final else 中清空自身。清楚了吗?
    • 如果找不到项目,现在清空列表。
    【解决方案4】:

    测试代码从 0 到 10 运行,但是当你提取一个元素时,会减小队列的大小。

    因此,如果队列最初是 10 个元素长,那么您提供的索引 i 最终将是队列长度的 &gt;=

    因此是IndexError

    尝试其他建议的代码段之一。

    【讨论】:

    • 明白。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-11-19
    • 1970-01-01
    • 2018-03-25
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多