Перечислять элементы в списке, чтобы пользователь мог выбрать числовое значение - PullRequest
2 голосов
/ 20 июня 2011

Я пытаюсь найти самый простой способ перечисления элементов в списке, чтобы пользователь не обременялся вводом длинного имени файла в командной строке. Приведенная ниже функция показывает пользователю все файлы .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 ]

8 голосов
/ 20 июня 2011

Начните со списка файлов:

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."
3 голосов
/ 20 июня 2011

Мне очень понравился ответ Йохена , но не понравилась множественная попытка / исключение. Вот вариант с использованием 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'
3 голосов
/ 20 июня 2011
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)
3 голосов
/ 20 июня 2011

Вы можете перечислить элементы и распечатать их с указателем. Вы можете использовать отображение, чтобы показывать пользователю непрерывные числа, даже если фактические индексы имеют пробелы:

 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.

...