我想从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:字符串长度不是项目大小的倍数
答案 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()))
这产生与上述选项相同的结果,但避免创建中间列表。
如果你想保留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()