【问题标题】:Python: list assignment out of rangePython:列表分配超出范围
【发布时间】:2010-03-11 14:11:05
【问题描述】:

这个模块是我用 Python 制作的一个简单的待办事项应用程序的一部分......

def deleteitem():
             showlist()
             get_item = int(raw_input( "\n Enter number of item to delete: \n"))
             f = open('todo.txt')
             lines = f.readlines()
             f.close()
             lines[get_item] = ""
             f = open('todo.txt','w')
             f.writelines(lines)
             f.close()
             showlist()

f 中的行数显然会随着项目添加到列表中而发生变化...这里的问题是,例如,如果用户在文件中只有 9 行时输入“10”(或其他任何不在范围内的行) ) ,它按预期退出:

IndexError: list assignment index out of range

我可以在模块中添加什么以使其提示用户输入范围内的项目?我假设可能是一个 Try 块......或者有没有办法捕捉异常......我猜有一个简单的方法可以做到这一点......

【问题讨论】:

    标签: python list error-handling


    【解决方案1】:

    在索引时捕获IndexError 或事先检查列表的len()

    【讨论】:

      【解决方案2】:

      先读取文件,然后循环询问用户,直到回答可以接受:

      while True:
          get_item = int(raw_input( "\n Enter number of item to delete: \n"))
          if get_item >=0 and get_item < len(lines):
              break
      

      当然,当文件为空并且不会向用户提供有关可接受值的任何提示时,它会中断。但是,让我们为您保留一些练习。

      【讨论】:

      • 添加一个很好的输出,向用户说明问题。
      【解决方案3】:

      对当前代码进行明智的更改:

      def deleteitem():
        showlist()
      
        with open("todo.txt") as f:
          lines = f.readlines()
        if len(lines) == 0:  # completely empty file
          return  # handle appropriately
        prompt = "Enter number to delete (1-%d), or 0 to abort: " % len(lines)
        while True:
          input = raw_input(prompt)
          try:
            input = int(input, 10)
          except ValueError:
            print "Invalid input."
          else:
            if 0 <= input <= len(lines):
              break
            print "Input out of range."
        if input == 0:
          return
        input -= 1  # adjust from [1,len] to [0,len)
      
        #del lines[input]  # if you want to remove that line completely
        lines[input] = "\n"  # or just make that line blank (what you had)
      
        with open("todo.txt", "w") as f:
          f.writelines(lines)
      
        showlist()
      

      【讨论】:

      • 谢谢,这行得通。我正在使用 Python 2.5.x ..所以我挂断了'with'。我在脚本中添加了“ from future__import__ with_statement ”,一切就绪。我认为在您的代码中,“ if len(lines) == 0:”行可能需要缩进? ...在我这样做之前我遇到了一个错误
      • @skylarking:它不应该需要缩进,并且该部分应该可以正常工作,就像我上面所说的那样。也许你不小心抄错了?
      • 很可能我在那里犯了一个错误......如果你好奇的话,我确实在这里发布了完整的待办事项应用程序作为答案。我相信那里也可能会发生很多改进
      【解决方案4】:

      试试这样的:

      def deleteitem():
      
      showlist()
      f = open('todo.txt')
      lines = f.readlines()
      f.close()
      if len(lines) == 0:
          print "File is empty!"
          return False
      print "File has %d items\n" % len(lines)
      item = 0
      while item < len(lines):
          item = raw_input( "\n Enter number of item to delete(0-%d): \n" % len(lines))
          item = int(item) # because of the width of the code
      f = open('todo.txt','w')
      f.write(lines[0:item-1])
      f.write(lines[item::])
      f.close()
      showlist()
      

      【讨论】:

        【解决方案5】:
        def deleteitem():
                     showlist()
                     get_item = int(raw_input( "\n Enter number of item to delete: \n"))
                     f = open('todo.txt')
                     lines = f.readlines()
                     f.close()
                     try:
                         lines[get_item] = ""
                     except Exception,err: 
                         print err
                     f = open('todo.txt','w')
                     f.writelines(lines)
                     f.close()
                     showlist()
        

        【讨论】:

        • Bare excepts 有一些有效的用途,但这不是其中之一。
        • 但这足以满足他的目的,并且可以完成工作。还有 cmets 吗?
        • 不,它没有。例如,如果您不幸在正确(或错误)的时间得到它,它将默默地吞下 KeyboardInterrupt。我尽可能地设计我的代码,使其即使在这种“不幸”的情况下也能按预期工作,并且不能从道德上推荐此代码。你纠正它有那么难吗?将“除:”更改为“除 IndexError:”。
        • except 捕获所有异常,那么默默地“吞下”KeyboardInterrupt 是什么意思。
        • @levis:KeyboardInterrupt 是一个异常,在这种情况下捕获它是错误。您的代码不会将异常向上传递,而是忽略/吞下它——隐藏它曾经存在过。
        【解决方案6】:

        为了它的价值......我将把代码放到我的 todo.py 程序中......这只是我从 OS X 的终端运行的东西,以控制我在工作中需要做的事情。 ..我敢肯定它非常不符合pythonic,效率低下和其他一切......但也许它会对偶然发现这个线程的人有用:

        from __future__ import with_statement
        import sys
        import os
        import fileinput
        
        os.system('clear')
        
        print ("##############          TO DO LIST       ############")
        print ("##############                           ############")
        
        def showlist():
            os.system('clear')
            print ("############  Current To Do List  ######")
            print ("########################################")
        
            get_list = open('todo.txt')
            entire_list = get_list.readlines()
            for i in range (len(entire_list)):
                print i, entire_list[i]
            get_list.close()
            print ("########################################")
            print ("########################################")
        
        def appendlist():
            print ("#######################################")
            print ("#######################################")
        
        
            addtolist = str( raw_input("Enter new item:  \n"))
            thelist = open('todo.txt', 'a')
            thelist.write(str(addtolist))
            thelist.write(str('\n'))
            thelist.close()  
            showlist()
        
        
        def deleteitem():
            showlist()
        
                with open("todo.txt") as f:
                    lines = f.readlines()
                    if len(lines) == 0:  
                        return  
                prompt = "Enter number to delete or '0' to abort: " 
                while True:
                        input = raw_input(prompt)
                        try:
                            input = int(input, 10)
                        except ValueError:
                            print "Invalid input."
                        else:
                            if 0 <= input <= len(lines):
                                break
                            print "Input out of range."
                if input == 0:
                          return
        
                lines[input] = "" 
        
                    with open("todo.txt", "w") as f:
                        f.writelines(lines)
        
                showlist()
        
        while True:
        
            askme = raw_input("\nDo you want to:\n(S)ee list\n(A)ppend list\n(D)elte from list\n(Q)Quit?\n")
            print str('\n')
        
            if askme == "S":
                showlist()
            elif askme == "A":
                appendlist()
            elif askme == "D":
                deleteitem()
        
            elif askme == "Q":
                sys.exit()
            else: 
                print ("Try again?")
        
        print ("#######################################")
        print ("#######################################")
        

        【讨论】:

        • 你要么混合制表符和空格,要么在 SO 上发布时缩进搞砸了。
        • 我想我选择了三连胜并设法完成了所有这三件事。只是对其进行了编辑以清理它。
        猜你喜欢
        • 2013-05-31
        • 1970-01-01
        • 2018-10-21
        • 2019-06-18
        • 2020-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-19
        相关资源
        最近更新 更多