PEP 8 implementation is great, now to focus on being concise -
While you have started writing immaculate programs, as in here and your current question, I believe you should start making your programs more concise. This decreases memory space and sometimes, makes your program faster. Also, I'm glad to see you've started implementing the if __name__ == '__main__'
guard.
Here's one approach you could use to make your program really concise and fast -
def zigzag(word: str, num_rows: int) -> str:
ans = [''] * num_rows
x = 0
direction = 1
for i in word:
ans[x] += i
if 0 <= x + direction < num_rows:
x += direction
else:
direction *= -1
x += direction
return ''.join(ans)
if __name__ == "__main__":
print(zigzag("PAYPALISHIRING", 3))
Here, I believe that it would be better if you don't declare word
and num_rows
before calling the function. This -
print(zigzag("PAYPALISHIRING", 3))
looks much shorter (and better) than -
word = "PAYPALISHIRING"
num_rows = 3
print("".join(line for array in zigzag() for line in array))
Also, (hey, I'm kind of like a beginner, so please correct me if I'm wrong) I feel that you should perform the .join()
function, or any other function really, in the principal function, as I have done above -
# rest of the principal function
return ''.join(ans)
Just use the if __name__ == __main__
guard to (simply) call the principal function and execute the entire program (you shouldn't really perform any other function(s) in it except calling the principal function to execute it) -
if __name__ == "__main__":
print(zigzag("PAYPALISHIRING", 3))
Also, I would rename increasing
to direction
as it suits this task better ("the value of "direction
" changes only when we have moved up to the topmost row or moved down to the bottommost row" (taken from Leetcode). If you're wondering what *=
means, it's just another way of doing x = x * 5
, which is specified here.
Also, you could make -
array = []
for _ in range(num_rows):
array.append([])
num_rows = 3
print(array)
# [[], [], []]
more concise by just simply initializing it -
array = [[] for _ in range(num_rows)] # Thanks to Maarten Fabré
num_rows = 3
print(array)
# [[], [], []]
See how concise you can get by doing this? This removes the need to use .append()
, which, in this case, is unnecessary (this will also take up less memory space).
I know the final line is a bit messy, and I could unpack it into a
two-line for loop but I really like single-line for loops.
Nah, don't worry. As far as I know,
print("".join(line for array in zigzag() for line in array))
is so much more concise than unpacking it into a two-line for
loop. I'm glad you like single-line for
loops :)
Here are the times taken for each function -
Your function -
%timeit "".join(line for array in zigzag() for line in array)
8.34 µs ± 834 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
My function -
%timeit zigzag("PAYPALISHIRING", 3)
4.19 µs ± 134 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
As you can see above, the time taken for execution has been approximately halved, which also shows that making your function concise, down to what I have done in my function, can make your program much faster.
Here is the Leetcode result for my program (if need be) -

Hope this helps!