2

我试图找到最直接的方法来枚举列表中的项目,这样用户就不会在命令行上键入长文件名。下面的函数向用户显示文件夹中的所有 .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
4

4 回答 4

8

从文件列表开始:

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."
于 2011-06-20T12:23:45.737 回答
3

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

 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将 userchoice 转换为dirlist.

于 2011-06-20T12:21:30.667 回答
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)
于 2011-06-20T12:22:30.200 回答
3

我真的很喜欢Jochen 的回答,但不喜欢多次尝试/例外。这是一个使用 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'
于 2011-06-20T13:37:55.297 回答