Reputation: 83
I am an undergraduate student who loves programming. I encountered a problem today and I don't know how to solve this problem. I looked for "Python - string to matrix representation" (Python - string to matrix representation) for help, but I am still confused about this problem.
The problem is in the following:
Given a string of whitespace separated numbers, create an nxn matrix (a 2d list where with the same number of columns as rows)and return it. The string will contain a perfect square number of integers. The int() and split() functions may be useful.
Example:
Input: '1 2 3 4 5 6 7 8 9'
Output: [[1,2,3],[4,5,6],[7,8,9]]
Example 2:
Input: '1'
Output: [[1]]
My answer:
import numpy as np
def string_to_matrix(str_in):
str_in_split = str_in.split()
answer = []
for element in str_in_split:
newarray = []
for number in element.split():
newarray.append(int(number))
answer.append(newarray)
print (answer)
The test results are in the following:
Traceback (most recent call last):
File "/grade/run/test.py", line 20, in test_whitespace
self.assertEqual(string_to_matrix('1 2 3 4'), [[1,2],[3,4]])
AssertionError: None != [[1, 2], [3, 4]]
Stdout:
[[4]]
as well as
Traceback (most recent call last):
File "/grade/run/test.py", line 15, in test_small
self.assertEqual(string_to_matrix('1 2 3 4'), [[1,2],[3,4]])
AssertionError: None != [[1, 2], [3, 4]]
Stdout:
[[4]]
as well as
Traceback (most recent call last):
File "/grade/run/test.py", line 10, in test_one
self.assertEqual(string_to_matrix('1'), [[1]])
AssertionError: None != [[1]]
Stdout:
[[1]]
as well as
Traceback (most recent call last):
File "/grade/run/test.py", line 25, in test_larger
self.assertEqual(string_to_matrix('4 3 2 1 8 7 6 5 12 11 10 9 16 15 14 13'), [[4,3,2,1], [8,7,6,5], [12,11,10,9], [16,15,14,13]])
AssertionError: None != [[4, 3, 2, 1], [8, 7, 6, 5], [12, 11, 10, 9], [16, 15, 14, 13]]
Stdout:
[[13]]
I am still confused how to solve this problem. Thank you very much for your help!
Upvotes: 2
Views: 5236
Reputation: 4700
Use split, create the 1D numpy array, then use reshape
:
>>> s = '1 2 3 4 5 6 7 8 9'
>>> np.array([s.split(), dtype=int).reshape(3,3)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
If you don't know the size of the array, but you know it's square (same width / height), then you can use math.sqrt
to get the inputs for reshape
:
>>> import math
>>> s = '1 2 3 4 5 6 7 8 9'
>>> arr = np.array(s.split(), dtype=int)
>>> size = int(math.sqrt(len(arr)))
>>> arr.reshape(size, size)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Upvotes: 1
Reputation: 1
import math
string = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16"
stringItems = string.split(" ")
numberOfItems = len(stringItems)
if math.sqrt(numberOfItems) - int(math.sqrt(numberOfItems)) == 0:
width = int(math.sqrt(numberOfItems))
array = []
finalArray = []
for i in range (0, width):
for j in range (0, width):
array.insert(j, stringItems[0])
stringItems.pop(0)
finalArray.insert(i, array)
array = []
print finalArray
else:
print "I require a string with length equal to a square number please"
Upvotes: -1
Reputation: 4501
import numpy as np
def string_to_matrix(str_in):
str_in_split = str_in.split()
numbers = list(map(int, str_in_split))
size = r_shape = int(np.sqrt(len(numbers)))
return np.array(numbers).reshape(r_shape, r_shape)
This is why you always got: AssertionError: None != ...
assertEqual(A, string_to_matrix("..."))
verifies if A
is equals to the value returned by string_to_matrix. In your code you don't return anything so it is None
The other issue is how you splitted the string, the easier options is to split everything and convert to number, and then reshape to sqrt(number of elements). This assumes that input length can be splited to form a nxn matrix
Upvotes: 0
Reputation: 16593
Assuming you don't want numpy
and want to use a list of lists:
def string_to_matrix(str_in):
nums = str_in.split()
n = int(len(nums) ** 0.5)
return list(map(list, zip(*[map(int, nums)] * n)))
nums = str_in.split()
splits by any whitespace, n
is the side length of the result, map(int, nums)
converts the numbers to integers (from strings), zip(*[map(int, nums)] * n)
groups the numbers in groups of n
, list(map(list, zip(*[map(int, nums)] * n)))
converts the tuples produced by zip
into lists.
Upvotes: 2
Reputation: 5606
Assuming you want to make this dynamic.
str_in = '1 2 3 4 5 6 7 8 9'
a = str_in.split(" ")
r_shape = int(math.sqrt(len(a)))
np.array([int(x) for x in a]).reshape(r_shape, r_shape)
Upvotes: 1
Reputation: 29742
Given that you will always get perfect square number of ints:
import numpy as np
input_strings = '1 2 3 4 5 6 7 8 9'
arr = np.array(input_strings.split(), dtype=int)
n = int(len(arr) ** 0.5)
arr.reshape(n, n)
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
Note: in your case, str.split
is better off without explicit sep
in order to work fine with multiple whitespaces in between the digits.
Upvotes: 0