Как читать stdin в массив 2D python целых чисел?
Я хотел бы прочитать 2d-массив целых чисел из stdin (или из файла) в Python.
нерабочий код:
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.читать()) ValueError: длина строки не кратна размеру элемента
3 ответов
несколько подходов для этого доступны. Ниже приведены некоторые из возможностей.
С помощью 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]]
Я никогда не пользовался такими.массив, поэтому мне пришлось немного покопаться.
ответ в сообщении об ошибке -
ValueError: длина строки не кратна размеру элемента
Как вы определяете размер? Ну, это зависит от типа, с которым вы его инициализировали. В вашем случае вы инициализировали его с Я, который является подписанный int. Итак, насколько велик int? Спросите своего интерпретатора python..
>>> a.itemsize
4
значение выше дается понимание проблемы. Ваша строка имеет ширину всего 11 байт. 11 не кратно 4. Но увеличение длины строки не даст вам массив {1,2,3,4,5,6}... Я не уверен, что это даст вам. Почему неопределенность? Ну, прочитайте строку документа ниже... (Уже поздно, поэтому я выделил важную часть, если вы хотите спать, как я!)
массив.fromfile(f, n) Читать n элементов (как машина значения) из объекта file f и добавьте их в конец массива. Если доступно менее n элементов, вызывается EOFError, но элементы, которые были доступны, по-прежнему вставляются в массив. f должен быть реальным встроенным файловым объектом; что-то еще с методом read() не будет делать.
массив.fromstring считывает данные так же, как и массив.fromfile. Обратите внимание на жирный шрифт выше. "как значения" означает "читает как двоичные". Итак, чтобы сделать то, что вы хотите сделать, вам нужно использовать модуль struct. Проверьте код под.
import struct
a = array.array('i')
binary_string = struct.pack('iiii', 1, 2, 3, 4)
a.fromstring(binary_string)
фрагмент кода выше загружает массив со значениями tlhe 1, 2, 3, 4; Как мы и ожидаем.
надеюсь, что это помогает.
arr = []
arr = raw_input()
Если вы хотите разделить входные данные на пробелы:
arr = []
arr = raw_input().split()