I have a list of strings. I need to list them in rows and columns. Each row should not have more than "cols" number of values. Each of the values in a given row should be "step" away from the previous value. The values should appear only once in the output. Here is what I have. Any better way to write this code?
cols = 4
step = 10
vlist = ["Value" + str(i+1) for i in range(100)]
vlen = len(vlist)
start = 0
while start < vlen and start < step:
num = 0
for idx in range(start, vlen, step):
if num < cols:
print(vlist[idx], end=", ")
num += 1
print("\n")
start += 1
3 Answers 3
Fancy iteration in Python is often made easier using the itertools
module. For this case, itertools.islice()
can help pick out the values for each row.
from itertools import islice
cols = 4
step = 10
vlist = ["Value" + str(i+1) for i in range(100)]
for row in range(step):
print(', '.join(islice(vlist, row, cols * step, step)), end=", \n\n")
The code can be made more understandable by:
- introducing row and column indices
- replace the while loop with a for loop
- calculate the index for
vlist
from the values of the row/col indices
This reduces the number of help variables needed and could result in something like this:
vlist = ["Value" + str(i+1) for i in range(100)]
cols = 4
rows = 10
for row_idx in range(rows):
for col_idx in range(cols):
idx = row_idx + rows * col_idx
print(vlist[idx], end=", ")
print("\n")
-
\$\begingroup\$ Thanks Jan. I used this approach as well. But your code looks cleaner :) \$\endgroup\$RebornCodeLover– RebornCodeLover2019年03月16日 20:24:24 +00:00Commented Mar 16, 2019 at 20:24
It can be solved by using the slice object.
slice - An object usually containing a portion of a sequence. A slice is created using the subscript notation, [] with colons between numbers when several are given, such as in variable_name[1:3:5]. The bracket (subscript) notation uses slice objects internally.
cols = 4
step = 10
vlist = ["Value" + str(i+1) for i in range(100)]
end = step * cols
for start in range(step):
print(', '.join(vlist[start:end:step]))
Output
Value1, Value11, Value21, Value31
Value2, Value12, Value22, Value32
Value3, Value13, Value23, Value33
Value4, Value14, Value24, Value34
Value5, Value15, Value25, Value35
Value6, Value16, Value26, Value36
Value7, Value17, Value27, Value37
Value8, Value18, Value28, Value38
Value9, Value19, Value29, Value39
Value10, Value20, Value30, Value40
-
\$\begingroup\$ Thank you @MinMax. 200_success also gave the same answer earlier. \$\endgroup\$RebornCodeLover– RebornCodeLover2019年03月17日 14:51:38 +00:00Commented Mar 17, 2019 at 14:51
-
\$\begingroup\$ @RebornCodeLover It is different. @200_success uses the
islice
fromitertools
. I use built-in slice. But yes, they are similar in other ways. \$\endgroup\$MiniMax– MiniMax2019年03月17日 14:56:16 +00:00Commented Mar 17, 2019 at 14:56
Each [value] should be "step" away from the previous value
an "external" requirement? ((Block-) Quote the specification of the result to achieve.) Another interpretation is In a monospace font, each value shall be output 10 places to the right of the preceding one, the advantage being all values getting displayed. \$\endgroup\$