以交互方式从列表中选择项目

时间:2014-02-23 01:16:55

标签: python

我需要将文件夹的内容打印给用户,然后用户选择其中一个文件。然后该程序采用该选择并在其他地方使用它。

我的代码实现了这个目标:

keylist = os.listdir('./SomeFolder/')
keycount = len(keylist)
for key in keylist:
    keynum = (keylist.index(key) + 1)
    print(str(keynum) + ' : ' + str(key))
while True:
    try:
        keychoice = int(input('Please Choose a Key : '))
        print()
        if 1 <= keychoice <= keycount:
            break
        else:
            raise MenuError()
    except ValueError:
        print('Please enter a valid option')
        continue
    except MenuError:
        print('Please enter a valid option, ' + str(keychoice) + " isn't an option.")
        continue

chosenkey = keylist[(keychoice - 1)]
print(chosenkey + ' has been chosen')

总的来说,这很好用。但是,有更好的方法吗?

我是python的新手,所以任何指针都会受到极大的欢迎。 我使用它的程序是pySignare 感谢。

3 个答案:

答案 0 :(得分:2)

我很快就会对此进行仔细研究,但跳出来的事情就是这样:

for key in keylist:
    keynum = (keylist.index(key) + 1)
    print(str(keynum) + ' : ' + str(key))

您正在使用list.index在迭代时查找密钥。不要那样做。

更好的做法是:

for i in range(len(keylist)):
    key = keylist[i]
    keynum = i
    print("{} : {}".format(keynum,key))

你应该这样做的真正方式是:

for keynum, key in enumerate(keylist):
    print("{} : {}".format(keynum + 1,key))

enumerate(iterable)遍历iterable并返回每个项目的元组,代表(index, value)。您正在解包那些keynum, key的人。为了适应您最初的效果,在显示之前添加一个keynum,然后再从用户输入中减去一个。

我还会创建一个定义整数输入的函数。类似的东西:

def int_input(prompt,range_=None):
    while True:
        in_ = input(prompt)
        try: in_ = int(in_)
        except ValueError: pass
        else:
            if not range or if in_ in list(range_): return in_
        print("Invalid value, please try again.")

这将允许您执行以下操作:

keylist = os.listdir("path/to/dir")
for i,key in enumerate(keylist):
    print("{} : {}".format(keynum+1, key))
chosen_key = int_input("Which dir? ",range(1,len(keylist)+1)) - 1
print ("{} has been chosen!".format(keylist[chosen_key]))

答案 1 :(得分:1)

我能提供的唯一改进是使用enumerate() function

keylist = os.listdir('./SomeFolder/')
keycount = len(keylist)

for keynum, key in enumerate(keylist, 1):
    print('{} : {}'.format(keynum, key))

我在1为您开始计数以匹配您的输出;无论如何,用户发现从1更自然计数。

这也使用了string formatting,这是一种更易读,更简洁的构建字符串的方法。

答案 2 :(得分:1)

你在这里做的两件值得避免的事情是True循环和缺乏功能。总的来说,我认为你可以更容易地完成你想要的东西:

def getChoice(path):
    file_list = os.listdir(path)
    for i,j in enumerate(file_list):
        print "{choice}: {f}".format(choice=i+1, f=j) #Index from one.
    user_choice = int(input("What file do you wish to use?"))

    if user_choice in range(len(file_list)):
        print "You chose {f}".format(f=file_list[user_choice - 1])
        return file_list[user_choice-1]
    else:
        print "That is not a valid selection."
        return False

然后我将函数调用包装起来,所以我有类似的东西:

choice = False
while not choice:
    choice = getChoice(path)

这样你可以避免使用while循环,并且你的getChoice函数可以独立测试其他任何东西。

注意:我没有测试这段代码,但它看起来不错。