1
\$\begingroup\$

The code below will print a 10x10 table of random numbers between 1-3.

Is there something to make the code faster?

Can the code be made more readable?

import random
import numpy as np
x = str(np.reshape([random.randint(1, 3) for i in range(100)], (-1, 10)).tolist()).replace("[", "").replace("]", "\n").replace("\n,", ",\n").replace("\n ", "\n").replace("\n\n", "")
print(end=x)

Example output

2, 3, 2, 1, 2, 1, 1, 2, 2, 1,
2, 1, 3, 2, 2, 3, 3, 2, 3, 3,
2, 3, 1, 2, 2, 2, 2, 1, 3, 1,
2, 2, 2, 2, 2, 3, 3, 2, 2, 2,
3, 1, 3, 1, 2, 3, 3, 3, 2, 2,
3, 3, 2, 3, 1, 3, 1, 2, 3, 3,
2, 2, 3, 3, 1, 3, 3, 1, 2, 2,
1, 1, 1, 2, 1, 2, 2, 3, 3, 2,
1, 3, 2, 2, 3, 1, 2, 2, 1, 2,
3, 1, 3, 1, 2, 3, 2, 1, 2, 3
\$\endgroup\$
5
\$\begingroup\$

Multiple lines

First off, don't try to do everything on one line. This line is doing way too much:

x = str(np.reshape([random.randint(1, 3) for i in range(100)], (-1, 10)).tolist()).replace("[", "").replace("]", "\n").replace("\n,", ",\n").replace("\n ", "\n").replace("\n\n", "")

Instead, separate the matrix creation from the formatting:

m = np.reshape([random.randint(1, 3) for i in range(100)], (-1, 10))
x = str(m.tolist()).replace("[", "").replace("]", "\n").replace("\n,", ",\n").replace("\n ", "\n").replace("\n\n", "")

Matrix creation

Numpy has built-in functions for generating random arrays, including random arrays of integers:

m = np.random.randint(1, 4, (10,10))

Matrix to string

Instead of converting the matrix to a list, and then to a string, simply use numpy's built-in array to string function np.array2string()

print(np.array2string(m, separator=", "))
  
[[2, 1, 3, 3, 2, 1, 2, 3, 2, 1],
 [1, 1, 1, 3, 2, 2, 3, 2, 3, 2],
 [2, 1, 3, 2, 3, 1, 2, 2, 3, 1],
 [1, 1, 3, 3, 3, 2, 3, 3, 3, 2],
 [3, 3, 1, 3, 3, 2, 1, 1, 1, 3],
 [3, 3, 2, 2, 3, 1, 3, 2, 2, 2],
 [2, 2, 1, 3, 1, 3, 3, 1, 3, 2],
 [3, 2, 3, 1, 1, 1, 3, 3, 3, 1],
 [1, 3, 1, 2, 1, 2, 1, 2, 2, 2],
 [3, 3, 2, 2, 2, 1, 2, 2, 1, 2]]

That is 90% of the way to the desired result. Just need to rip off the two leading and trailing brackets, and adjust the line joining:

print(np.array2string(m, separator=", ")[2:-2].replace("],\n [", ",\n"))
  
2, 1, 3, 3, 2, 1, 2, 3, 2, 1,
1, 1, 1, 3, 2, 2, 3, 2, 3, 2,
2, 1, 3, 2, 3, 1, 2, 2, 3, 1,
1, 1, 3, 3, 3, 2, 3, 3, 3, 2,
3, 3, 1, 3, 3, 2, 1, 1, 1, 3,
3, 3, 2, 2, 3, 1, 3, 2, 2, 2,
2, 2, 1, 3, 1, 3, 3, 1, 3, 2,
3, 2, 3, 1, 1, 1, 3, 3, 3, 1,
1, 3, 1, 2, 1, 2, 1, 2, 2, 2,
3, 3, 2, 2, 2, 1, 2, 2, 1, 2

Print without newline

print(end=x) is being too obfuscated. You are not using the entire result as a line ending.

If you want to print the result without a newline at the end, use end='', like:

print(x, end='')

Improved code

import numpy as np

m = np.random.randint(1, 4, (10,10))
x = np.array2string(m, separator=", ")[2:-2].replace("],\n [", ",\n")
print(x, end='')
\$\endgroup\$
2
  • \$\begingroup\$ does multiline works the perfomace? \$\endgroup\$
    – Fmbalbuena
    Dec 23 '21 at 17:19
  • 2
    \$\begingroup\$ I'm having difficulty parsing what you mean by that comment, but with any printing, performance is limited by the I/O device (console, file). Converting the numpy matrix into a list of lists and then converting that into a string would not be performant; using numpy's built-in array2string function should always be faster. A single .replace() call should be about 5 times faster than having 5 .replace() calls. \$\endgroup\$
    – AJNeufeld
    Dec 23 '21 at 17:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.