input() 函数的输入可以有多大?

Posted

技术标签:

【中文标题】input() 函数的输入可以有多大?【英文标题】:How big can the input to the input() function be? 【发布时间】:2017-03-28 15:57:51 【问题描述】:

我提供给input() 函数的输入可以有多大?

不幸的是,没有简单的方法来测试它。在使用大量复制粘贴后,我无法让input 在我提供的任何输入上失败。 (我最终放弃了)

input 函数的 documentation 没有提及任何相关内容:

如果存在prompt 参数,则将其写入标准输出,不带尾随换行符。然后该函数从输入中读取一行,将其转换为字符串(去除尾随的换行符),然后返回。读取 EOF 时,会引发 EOFError

所以,我猜没有限制?有谁知道有没有,如果有,多少钱?

【问题讨论】:

相关:***.com/q/1739913/5647260 使用大量复制粘贴后”你试过redirecting stdin吗? 我没有@RyanHaining,谢谢! 【参考方案1】:

当然有,不能无限*。我认为需要强调的文档中的关键语句是:

[...] 然后该函数从输入中读取一行,将其转换为字符串(去除尾随的换行符)[...]

(强调我的)

由于它将您提供的输入转换为 Python str 对象,因此它本质上转换为:“其大小必须小于或等于最大字符串Python可以创建”。

没有给出明确大小的原因可能是因为这是一个实现细节。对 Python 的所有其他实现强制执行最大大小没有多大意义。

*至少在 CPython 中,字符串的最大大小取决于其 index 允许的大小(请参阅PEP 353)。也就是当你尝试索引时,括号[]中的数字允许多大:

>>> s = ''
>>> s[2 ** 63]

IndexErrorTraceback (most recent call last)
<ipython-input-10-75e9ac36da20> in <module>()
----> 1 s[2 ** 63]

IndexError: cannot fit 'int' into an index-sized integer

(用2 ** 63 - 1试试前一个,这是可接受的正限制,-2 ** 63是负限制。)

对于索引,内部使用的不是 Python 数字;相反,它是Py_ssize_t,它分别是 32/64 位机器上的有符号 32/64 位 int。所以,这就是看起来的硬性限制。

(如错误消息所述,int 和 intex-sized integer 是两个不同的东西)

如果在转换之前提供的输入大于PY_SSIZE_T_MAXPy_ssize_t 的最大大小),它也看起来像input() explicitly checks:

if (len > PY_SSIZE_T_MAX) 
    PyErr_SetString(PyExc_OverflowError,
                    "input: input too long");
    result = NULL;

然后它将输入转换为 Python strPyUnicode_Decode


为了让您了解这一点;如果平均一本书是500.000字符长,而estimation的书籍总数约为1.3亿,理论上你可以input左右:

>>> ((2 ** 63) - 1) // 500000 * 130000000
141898

乘以这些字符;不过,这可能会花费您一些时间 :-)(而且您首先会受到可用内存的限制!)

【讨论】:

How long is a [piece of] string? 我在交互式会话 (linux xterm) 中尝试了这个,得到了非常奇怪的反应(使用鼠标中键粘贴了大约 30k 个字符后),看起来字符串的打印速度非常慢(每行 1 行)第二)。可能不是 Python 的问题,而是 readline/xterm 速度变慢,或者您有其他想法是什么原因造成的? 我同意你的观点,因为 Python 的错是没有意义的。我真的怀疑为顺利处理 30k 字符转储而构建的交互式会话,但我又没有研究过那些@mkiever 我猜这实际上破坏了交互会话的某些部分。它仍在打印,不能用 Ctrl-c 停止,必须被杀死。这些天我需要更详细地检查一下。 这个数字仍然太大,对我来说没有任何意义。如果这本书的每个字符都包含整个 google 索引,那么您将拥有大约 2-4 本书。【参考方案2】:

我们可以很容易地通过实验找到答案。制作两个文件:

make_lines.py:

num_lines = 34

if __name__ == '__main__':
    for i in range(num_lines):
        print('a' * (2 ** i))

read_input.py:

from make_lines import num_lines

for i in range(num_lines):
    print(len(input()))

然后在 Linux 或 OSX 中运行此命令(我不知道 Windows 等效):

python make_lines.py | python3 read_input.py

在我的计算机上,它设法完成,但到最后却很挣扎,显着减慢了其他进程。它打印的最后一件事是8589934592,即 8 GiB。您可以根据自己对时间和内存限制可接受的定义来找出适合自己的价值。

【讨论】:

以上是关于input() 函数的输入可以有多大?的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2080 夹角有多大II

HDU 2076 夹角有多大(题目已修改,注意读题)

HDU 2076 夹角有多大(题目已修改,注意读题)

python中input函数可以通过格式控制字符串来限定输入的数据吗?

Python 内置函数raw_input()和input()用法和区别

python3:input() 函数