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

时间:2022-03-06 21:32:50

I would like to read a 2d array of integers from stdin (or from a file) in Python.

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

Non-working code:

非工作代码:

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())

This gives me an error: a.fromstring(stdin.read()) ValueError: string length not a multiple of item size

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

3 个解决方案

#1


9  

Several approaches to accomplish this are available. Below are a few of the possibilities.

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

Using an array

From a list

Replace the last line of code in the question with the following.

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

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

Now:

现在:

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

Con: does not preserve 2d structure (see comments).

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

From a generator

Note: this option is incorporated from comments by eryksun.

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

A more efficient way to do this is to use a generator instead of the list. Replace the last two lines of the code in the question with:

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

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

This produces the same result as the option above, but avoids creating the intermediate list.

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

Using a NumPy array

If you want the preserve the 2d structure, you could use a NumPy array. Here's the whole example:

如果要保留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)

Now:

现在:

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

Using standard lists

It is not clear from the question if a Python list is acceptable. If it is, one way to accomplish the goal is replace the last two lines of the code in the question with the following.

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

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

After running this, we have:

运行之后,我们有:

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

#2


2  

I've never used array.array, so I had to do some digging around.

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

The answer is in the error message -

答案在错误信息中 -

ValueError: string length not a multiple of item size

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

How do you determine the item size? Well it depends on the type you initialized it with. In your case you initialized it with i which is a signed int. Now, how big is an int? Ask your python interpreter..

你如何确定项目大小?那么它取决于你初始化它的类型。在您的情况下,您使用i进行初始化,这是一个signed int。现在,int有多大?问你的python翻译..

>>> a.itemsize
4

The value above provides insight into the problem. Your string is only 11 bytes wide. 11 isn't a multiple of 4. But increasing the length of the string will not give you an array of {1,2,3,4,5,6}... I'm not sure what it would give you. Why the uncertainty? Well, read the docstring below... (It's late, so I highlighted the important part, in case you're getting sleepy, like me!)

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

array.fromfile(f, n) Read n items (as machine values) from the file object f and append them to the end of the array. If less than n items are available, EOFError is raised, but the items that were available are still inserted into the array. f must be a real built-in file object; something else with a read() method won’t do.

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

array.fromstring reads data in the same manner as array.fromfile. Notice the bold above. "as machine values" means "reads as binary". So, to do what you want to do, you need to use the struct module. Check out the code below.

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

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

The code snippet above loads the array with tlhe values 1, 2, 3, 4; like we expect.

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

Hope it helps.

希望能帮助到你。

#3


-1  

arr = []
arr = raw_input()

If you want to split the input by spaces:

如果要按空格分割输入:

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

#1


9  

Several approaches to accomplish this are available. Below are a few of the possibilities.

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

Using an array

From a list

Replace the last line of code in the question with the following.

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

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

Now:

现在:

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

Con: does not preserve 2d structure (see comments).

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

From a generator

Note: this option is incorporated from comments by eryksun.

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

A more efficient way to do this is to use a generator instead of the list. Replace the last two lines of the code in the question with:

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

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

This produces the same result as the option above, but avoids creating the intermediate list.

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

Using a NumPy array

If you want the preserve the 2d structure, you could use a NumPy array. Here's the whole example:

如果要保留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)

Now:

现在:

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

Using standard lists

It is not clear from the question if a Python list is acceptable. If it is, one way to accomplish the goal is replace the last two lines of the code in the question with the following.

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

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

After running this, we have:

运行之后,我们有:

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

#2


2  

I've never used array.array, so I had to do some digging around.

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

The answer is in the error message -

答案在错误信息中 -

ValueError: string length not a multiple of item size

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

How do you determine the item size? Well it depends on the type you initialized it with. In your case you initialized it with i which is a signed int. Now, how big is an int? Ask your python interpreter..

你如何确定项目大小?那么它取决于你初始化它的类型。在您的情况下,您使用i进行初始化,这是一个signed int。现在,int有多大?问你的python翻译..

>>> a.itemsize
4

The value above provides insight into the problem. Your string is only 11 bytes wide. 11 isn't a multiple of 4. But increasing the length of the string will not give you an array of {1,2,3,4,5,6}... I'm not sure what it would give you. Why the uncertainty? Well, read the docstring below... (It's late, so I highlighted the important part, in case you're getting sleepy, like me!)

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

array.fromfile(f, n) Read n items (as machine values) from the file object f and append them to the end of the array. If less than n items are available, EOFError is raised, but the items that were available are still inserted into the array. f must be a real built-in file object; something else with a read() method won’t do.

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

array.fromstring reads data in the same manner as array.fromfile. Notice the bold above. "as machine values" means "reads as binary". So, to do what you want to do, you need to use the struct module. Check out the code below.

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

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

The code snippet above loads the array with tlhe values 1, 2, 3, 4; like we expect.

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

Hope it helps.

希望能帮助到你。

#3


-1  

arr = []
arr = raw_input()

If you want to split the input by spaces:

如果要按空格分割输入:

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