如何将stdin读取为2d python数组的整数?

k10*_*107 8 python arrays stdin

我想从Python中读取stdin(或文件)中的2d整数数组.

非工作代码:

from StringIO import StringIO
from array import array

# fake stdin
stdin = StringIO("""1 2
3 4
5 6""")

a = array('i')
a.fromstring(stdin.read())
Run Code Online (Sandbox Code Playgroud)

这给了我一个错误:a.fromstring(stdin.read())ValueError:字符串长度不是项目大小的倍数

Dav*_*ber 12

有几种方法可以实现这一目标.以下是一些可能性.

用一个 array

从列表中

用以下内容替换问题中的最后一行代码.

a.fromlist([int(val) for val in stdin.read().split()])
Run Code Online (Sandbox Code Playgroud)

现在:

>>> a
array('i', [1, 2, 3, 4, 5, 6])
Run Code Online (Sandbox Code Playgroud)

Con:不保留2d结构(参见注释).

从发电机

注意:此选项由eryksun的评论合并而成.

更有效的方法是使用生成器而不是列表.用以下代码替换问题中代码的最后两行:

a = array('i', (int(val) for row in stdin for val in row.split()))
Run Code Online (Sandbox Code Playgroud)

这会产生与上述选项相同的结果,但避免创建中间列表.

使用NumPy数组

如果你想保留2d结构,你可以使用NumPy数组.这是整个例子:

from StringIO import StringIO
import numpy as np

# fake stdin
stdin = StringIO("""1 2
3 4
5 6""")

a = np.loadtxt(stdin, dtype=np.int)
Run Code Online (Sandbox Code Playgroud)

现在:

>>> a
array([[1, 2],
       [3, 4],
       [5, 6]])
Run Code Online (Sandbox Code Playgroud)

使用标准列表

从问题中不清楚Python列表是否可以接受.如果是,实现目标的一种方法是用以下内容替换问题中代码的最后两行.

a = [map(int, row.split()) for row in stdin]
Run Code Online (Sandbox Code Playgroud)

运行之后,我们有:

>>> a
[[1, 2], [3, 4], [5, 6]]
Run Code Online (Sandbox Code Playgroud)

  • @David Alber:你可以从`array`获取缓冲区并从中生成一个NumPy数组:`b = np.frombuffer(a,dtype ='int32'); b.shape =(3,2)`.行在内存中是连续的. (2认同)
  • 我忘了添加,在这种情况下,Python`array`和NumPy`ndarray`共享相同的内存,因此更改一个会改变另一个内存.此外,使用生成器而不是列表创建数组会更有效:`a = array('i',(st(.)中的v的int(v).)split()))`. (2认同)