有没有办法使用 while 循环函数作为列表跟踪器?并与 FileI/O 混合?

问题描述 投票:0回答:1
to_do_list = []
while True:
    in_listed = input('item list:')
    
    if in_listed == 'quit':
        break
        
    if in_listed[0] == 'add':
        num1 = int(user_li[-1])
        to_do_list.append(num1 - 1)
        to_do_list.append(num1 - 1)  
    
        print(to_do_list)

    elif in_listed[0] == 'rm':
        num1 = int(user_li[1])
        to_do_list.pop(num1 + 1)
        to_do_list.pop(num1 + 1)
    
        print(to_do_list)
    
    elif in_listed[0] == 'ls':
        for i in range(len(to_do_list)-1):
            print(f'{i} {to_do_list[i]}, {to_do_list[i+1]}')

它有效,但我想使用

add
添加一个项目,然后添加一个带有日期的项目。例如,当我输入
add 5/5 buy milk
时,输出将是
['5/5', 'buy milk']

python-3.x sorting input while-loop file-io
1个回答
0
投票

修复您的
in_listed[0] == 'add'
测试

如果要将输入字符串分成单词列表,可以使用

strip
split
:

in_listed = input('item list: ').strip().split()

然后您可以安全地测试

in_listed[0]
"add"
"rm"
"quit"
之间的相等性。

读取-求值-打印循环

您正在实现的称为“shell”或“读取-评估-打印循环”。我建议简化循环的核心,以便它读取输入、识别命令并调用适当的命令;每个命令的单独代码可以分开并放入函数中,而不是在循环内的巨大if/elif/else

森林中。

这是简化后循环的样子:

env = { 'todo_list': [], 'prompt': '$ ', 'didntQuit': True } command_dict = {'add': cmd_add, 'rm': cmd_rm, 'print': cmd_print_todolist, 'quit': cmd_quit} while env['didntQuit']: argv = input(env['prompt']).strip().split() # read command = command_dict.get(argv[0], cmd_notfound) # identify command ret = command(argv) # execute command print_return_value(ret, argv) # error message if command failed
我们有一个字典

command_dict

,其中包含所有命令的名称。在 while 循环体中,我们读取输入;将其拆分为单词列表;在命令字典中查找输入的第一个单词;然后我们评估在字典中找到的命令(如果我们没有找到具有该名称的命令,则为 
cmd_notfound
)。

然后我们可以在 while 循环之外定义函数

cmd_add

cmd_rm
cmd_print_todolist
cmd_quit

请注意,我将所有全局变量移至名为

env

(“环境”)的单个字典中,因为我对全局变量持谨慎态度,并且更喜欢将它们全部放在一个地方。

完整代码

完整代码如下:

env = { 'todo_list': [], 'prompt': '$ ', 'replname': 'repl-todolist', 'didntQuit': True } def cmd_add(argv): if len(argv) > 2: date = argv[1] item = ' '.join(argv[2:]) elif len(argv) == 2: date = '' item = argv[1] else: return -1 env['todo_list'].append((date, item)) return 0 def cmd_rm(argv): if len(argv) < 2: print('rm: please specify the index of the item you want to remove') return -1 try: i = int(argv[1]) env['todo_list'].pop(i) return 0 except ValueError: print('rm: failed to interpret "{}" as a list index'.format(argv[1])) return -1 except IndexError: print('rm: index out of range') return -1 def cmd_print_todolist(argv): print('TODO:') for i, (date, item) in enumerate(env['todo_list']): print(' ({}) {} {}'.format(i, date, item)) return 0 def cmd_quit(argv): env['didntQuit'] = False return 0 def cmd_notfound(argv): print('{}: {}: command not found'.format(env['replname'], argv[0])) return -1 def print_return_value(ret, argv): if ret != 0: print('{}: command {} failed with return value {}'.format(env['replname'], argv[0], ret)) command_dict = {'add': cmd_add, 'rm': cmd_rm, 'print': cmd_print_todolist, 'quit': cmd_quit} while env['didntQuit']: argv = input(env['prompt']).strip().split() # read ret = command_dict.get(argv[0], cmd_notfound)(argv) # eval print_return_value(ret, argv) # error message
文件输入/输出

通过这种方式构建代码,添加新命令变得很简单。只需编写一个新函数,并将其添加到命令字典中即可!

我建议你阅读Python中文件I/O的教程:

读写文件的官方文档

这是一个

"save"

 命令的示例,它将待办事项列表写入文件:

def cmd_save(argv): if len(argv) < 2: print('save: please specify a filename to save the todo-list to') return -1 filename = argv[1] try: with open(filename, 'w') as outf: for i, (date, item) in enumerate(env['todo_list']): outf.write('TODO:\n') for i, (date, item) in enumerate(env['todo_list']): outf.write(' ({}) {} {}\n'.format(i, date, item)) return 0 except: print('save: unable to open file "{}"'.format(argv[1])) return -1
然后可以将此功能添加到命令字典中:

command_dict = {'save': cmd_save, 'add': cmd_add, 'rm': cmd_rm, 'print': cmd_print_todolist, 'quit': cmd_quit}
日期和待办事项列表排序

有一个名为

datetime

 的 Python 模块,如果您需要解析、操作或打印日期和时间,它真的很酷。
我建议修改函数 
cmd_add,将行
date = argv[1]
替换为更复杂的内容:
def cmd_add(argv):
    if len(argv) > 2:
        date = datetime.datetime.strptime(argv[1],"%m/%d").replace(datetime.datetime.today().year)
        item = ' '.join(argv[2:])
    elif len(argv) == 2:
        date = datetime.datetime.today()
        item = argv[1]
    else:
        return -1
    env['todo_list'].append((date, item))
    env['todo_list'].sort(key=lambda item: item[0])
    return 0

以下是新功能:

现在
    date
  • 不再是一个字符串,而是一个
    datetime
    对象;
    由于用户没有指定年份,所以我将今天的年份添加到日期中(另请参见
  • 这个答案
  • ); 如果用户未指定日期,我们将添加带有今天日期的项目;
  • 我在函数末尾添加了
  • .sort()
  • 。现在您的待办事项列表已按日期排序!
    
    
  • 由于日期是一个日期时间对象,我们还想修改
cmd_print_todolist

并以良好的格式打印时间:

def cmd_print_todolist(argv):
    print('TODO:')
    for i, (date, item) in enumerate(env['todo_list']):
        print('  ({}) {} {}'.format(i, date.strftime('%m/%d'), item))
    return 0

我使用 
'%m/%d'

来格式化日期,但您可以更奇特地添加星期几,或者用文字写出月份等。有关日期解析的更多信息,请参阅关于

strptime 和 strftime 行为
的文档和日期打印。

© www.soinside.com 2019 - 2024. All rights reserved.