如何在Python中优雅地重定义input函数以从预设列表中逐个返回值

本文介绍两种pythonic方式重定义内置input函数,使其从预设列表中按序返回值,避免使用全局变量和手动计数器,提升代码简洁性与可维护性。

在测试交互式程序(如算法题、命令行工具或教学示例)时,常需用预设输入替代真实用户输入,以实现可重复、自动化的验证。虽然可通过global+计数器实现(如原始代码),但该方式冗余、易出错,且违背Python的简洁哲学。

更优雅的解决方案是利用Python的迭代器协议——将输入序列转换为迭代器,并将其__next__方法直接赋值给input标识符:

raw_data = ['8', '2', '1']
input = iter(raw_data).__next__

for _ in range(3):
    print(input())  # 输出: 8, 2, 1

✅ 优势:

  • 无状态变量,无需global;
  • 纯函数式,线程安全(在单次执行中);
  • iter(...).__next__ 是标准迭代器接口,语义清晰;
  • 若列表耗尽,会抛出StopIteration(与真实迭代器行为一致,便于捕获异常)。

另一种轻量写法是复用list.pop(),但需注意顺序:

raw_data = ['1', '2', '8']  # 注意:需倒序准备,因pop默认从末尾移除
input = raw_data.pop

for _ in range(3):
    print(input())  # 输出: 8, 2, 1

⚠️ 注意事项:

  • pop()会原地修改列表,若需保留原始数据,请改用iter().__next__;
  • 若输入为多行文本(如OJ题目样例),推荐使用splitlines()构建迭代器:
    input = iter('''8
    2
    1'''.splitlines()).__next__

    此方式天然支持字符串输入,且与真实input()返回类型(str)完全一致。

总结:优先选用 iter([...]).__next__ 方案——它语义明确、不可变、符合Python惯用法,是真正“Pythonic”的输入模拟实践。