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

时间:2011-11-19 06:35:19

标签: 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())

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

3 个答案:

答案 0 :(得分:12)

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

使用array

从列表中

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

a.fromlist([int(val) for val in stdin.read().split()])

现在:

>>> a
array('i', [1, 2, 3, 4, 5, 6])

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

来自发电机

注意:此选项包含在eryksun的评论中。

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

a = array('i', (int(val) for row in stdin for val in row.split()))

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

使用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)

现在:

>>> a
array([[1, 2],
       [3, 4],
       [5, 6]])

使用标准列表

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

a = [map(int, row.split()) for row in stdin]

运行之后,我们有:

>>> a
[[1, 2], [3, 4], [5, 6]]

答案 1 :(得分:2)

我从未使用过array.array,所以我不得不做一些挖掘。

答案在错误信息中 -

ValueError:字符串长度不是项目大小的倍数

如何确定物品尺寸?那么它取决于你初始化它的类型。在您的情况下,您使用 i 初始化它,这是一个signed int。现在,int有多大?问你的python口译员..

>>> a.itemsize
4

上述值可提供对问题的深入了解。你的字符串只有11个字节宽。 11不是4的倍数。但是增加字符串的长度不会给你一个{1,2,3,4,5,6}的数组......我不确定它会给你什么。为什么不确定?那么,请阅读下面的文档字符串...(已经很晚了,所以我强调了重要的部分,以防你像我一样困倦!)

array.fromfile(f,n) 从文件对象f中读取n个项目(作为机器值)并将它们附加到数组的末尾。如果少于n个项目可用,则会引发EOFError,但可用的项目仍会插入到阵列中。 f必须是一个真正的内置文件对象;使用read()方法的其他东西不会。

array.fromstring以与array.fromfile相同的方式读取数据。注意上面的粗体。 “作为机器值”意味着“读取为二进制”。因此,要执行您想要执行的操作,您需要使用struct模块。看看下面的代码。

import struct
a = array.array('i')
binary_string = struct.pack('iiii', 1, 2, 3, 4)
a.fromstring(binary_string)

上面的代码片段使用值1,2,3,4加载数组;就像我们期望的那样。

希望它有所帮助。

答案 2 :(得分:-1)

arr = []
arr = raw_input()

如果要按空格分割输入:

arr = []
arr = raw_input().split()