Ok: you have to define a function called numCol
which takes one integer argument:
def numCol(n):
then you have to print a line consisting of n
characters, where every tenth character is an incrementing integer and every other character is a space.
chars = []
for i in range(1, n+1):
if i % 10:
chars.append(" ")
else:
chars.append(str((i % 100) // 10))
print(''.join(chars))
and finally a row consisting of 'n' chars, being 1234567890 repeating:
chars = []
for i in range(1, n+1):
chars.append(str(i % 10))
print(''.join(chars))
which then runs as
>>> numCol(65)
1 2 3 4 5 6
12345678901234567890123456789012345678901234567890123456789012345
Edit:
In response to @AdamSmith:
Let's see some actual numbers:
from textwrap import dedent
from timeit import Timer
test_statements = [
(
"n = 65",
"""
# as a for-loop
chars = []
for i in xrange(1, n+1):
if i % 10:
chars.append(" ")
else:
chars.append(str((i % 100) // 10))
"""
),
(
"n = 65",
"""
# as a list comprehension
chars = [" " if i%10 else str((i%100)//10) for i in xrange(1,n+1)]
"""
),
(
"n = 65",
"""
# extra cost of list-to-string
chars = [" " if i%10 else str((i%100)//10) for i in xrange(1,n+1)]
s = ''.join(chars)
"""
),
(
"n = 65",
"""
# vs cost of generator-to-string
chars = (" " if i%10 else str((i%100)//10) for i in xrange(1,n+1))
s = ''.join(chars)
"""
),
(
"s = ' 1 2 3 4 5 6 '",
"""
# cost of actually displaying string
print(s)
"""
)
]
for setup,run in test_statements:
res = Timer(dedent(run), setup)
times = res.repeat() # 3 * 1000000 runs
print("{:7.1f}".format(min(times)) # time of one loop in microseconds
on my system (i5-760, Win7 x64, Python 2.7.5 64bit) this gives
15.1 # for-loop -> list of chars
10.7 # list comprehension -> list of chars
11.4 # list comprehension -> string
13.6 # generator expression -> string
132.1 # print the string
Conclusions:
a list comprehension is 29% faster than a for-loop at building a list of characters
a generator expression is 19.6% slower than a list comprehension at building a list of characters and joining to a string
it's pretty much irrelevant, because actually printing the output takes 9 times longer than generating it with any of these methods - by the time you print the string out, using a list comprehension (fastest) is just 2.9% faster than the for-loop (slowest).
@user3482104
If you really want to avoid if ... else
, you can do
if stmt:
do_a()
if not stmt: # same effect as 'else:'
do_b()
but be aware that this has to evaluate stmt
twice where else
only evaluates it once.
Also, because both loops are iterating over the same range (same start/end values), you can combine the loops:
def numCol(n):
firstline = []
secondline = []
for i in range(1, n+1):
i %= 100
tens, ones = i // 10, i % 10
if ones: # ones != 0
firstline.append(" ")
if not ones: # ones == 0 # <= 'else:'
firstline.append(str(tens))
secondline.append(str(ones))
print(''.join(firstline))
print(''.join(secondline))