【问题标题】:Enumerate items in a list so a user can select the numeric value枚举列表中的项目,以便用户可以选择数值
【发布时间】:2011-06-20 12:17:05
【问题描述】:

我试图找到最直接的方法来枚举列表中的项目,这样用户就不会在命令行上键入长文件名。下面的函数向用户显示文件夹中的所有 .tgz 和 .tar 文件……然后允许用户输入他要提取的文件的名称。这对用户来说是乏味且容易出现语法错误的。我希望用户只需选择一个与文件关联的数值(例如 1、2、3 等)。有人可以给我一些指导吗?谢谢!

  dirlist=os.listdir(path)

  def show_tgz():
     for fname in dirlist:
          if fname.endswith(('.tgz','.tar')):
             print '\n'
             print fname

【问题讨论】:

    标签: python enumerate


    【解决方案1】:

    从文件列表开始:

    files = [fname for fname in os.listdir(path) 
                   if fname.endswith(('.tgz','.tar'))]
    

    现在你可以直接enumerate他们:

    for item in enumerate(files):
        print "[%d] %s" % item
    
    try:
        idx = int(raw_input("Enter the file's number"))
    except ValueError:
        print "You fail at typing numbers."
    
    try:
        chosen = files[idx]
    except IndexError:
        print "Try a number in range next time."
    

    【讨论】:

    • 您不应该将最后一行设为单行。单行代码有时难以理解,也难以调试。另外,您的代码假定用户没有输入错误。不过,我知道此代码仅用于说明目的。
    • 我实际上比我的解决方案更喜欢这个。
    • 哦,太好了,我没有意识到 endswith 后缀 arg 也可以是要查找的后缀元组!
    【解决方案2】:

    您可以枚举项目,并使用索引打印它们。您可以使用映射向用户显示连续数字,即使实际索引有间隙:

     def show_tgz():
         count = 1
         indexMapping = {}
         for i, fname in enumerate(dirlist):
             if fname.endswith(('.tgz','.tar')):
                 print '\n{0:3d} - {1}'.format(count, fname)
                 indexMapping[count] = i
                 count += 1
         return indexMapping
    

    然后您可以使用indexMapping 将用户选择转换为dirlist 中的正确索引。

    【讨论】:

    • 如何翻译 indexMapping。另外,我应该从 show_tgz() 函数内部提示用户吗?
    【解决方案3】:
    def gen_archives(path):
        names = os.listdir(path)
        for name in names:
            if name.endswith(('.tgz', '.tar'))
                yield name
    
    for i, name in enumerate( gen_archives(path) ):
        print "%d. %s" % (i, name)
    

    【讨论】:

      【解决方案4】:

      我真的很喜欢Jochen's answer,但不喜欢多次尝试/除外。这是一个使用 dict 的变体,它将循环直到做出有效的选择。

      files = dict((str(i), f) for i, f in
                    enumerate(f for f in os.listdir(path) if f.endswith(('.tgz','.tar'))))
      for item in sorted(files.items()):
          print '[%s] %s' % item
      choice = None
      while choice is None:
          choice = files.get(raw_input('Enter selection'))
          if not choice:
              print 'Please make a valid selection'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-26
        • 2021-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多