Python: print without overwriting printed lines - python

I have
for i in range(0, 11): print i, "\n", i
I'd like my python program to print this way for each for loop
1st loop:
1
1
2nd loop:
1
2
2
1
3rd loop:
1
2
3
3
2
1
I've tried using \r\n or \033[1A but they just overwrite the previous line. Is there a way I can "push" the outputted line down so I don't overwrite it?

One way to do this,
def foo(x, limit):
if x < limit :
print x
foo(x + 1, limit)
print x
foo(1, 11)

It's not possible to do it in 1 for loop as you're currently trying.
As I suggested, you can do it like this by using lists
>>> l1 = []
>>> l2 = []
>>> for i in range(0, 11):
... l1.append(i)
... l2 = [i] + l2
>>> l1.extend(l2)
>>> for i in l1:
... print i
0
1
2
3
4
5
6
7
8
9
10
10
9
8
7
6
5
4
3
2
1
0

Concatenation of two list generators.
>>> ladder = [x for x in range(5)] + [x for x in range(5,-1,-1)]
>>> ladder
[0, 1, 2, 3, 4, 5, 4, 3, 2, 1, 0]
>>> for x in ladder:
... print x
...
0
1
2
3
4
5
4
3
2
1
0
>>>

one of ways to solve this
def two_side_print(start, end):
text = [str(i) for i in range(start,end)]
print '\n'.join(text), '\n', '\n'.join(reversed(text))
two_side_print(1, 11)

Another option is to save the printed values in a list and print that list in reverse order in each loop iteration.
My suggestion:
l = []
for i in range(1, 5):
print 'Loop '+str(i) # This is to ease seeing the printing results
for val in l:
print val
print i
l.insert(len(l),i)
for val in reversed(l):
print val
The output for a loop iterating from 0 to 5:
Loop 1
1
1
Loop 2
1
2
2
1
Loop 3
1
2
3
3
2
1
Loop 4
1
2
3
4
4
3
2
1
I hope this is what you are looking for.

You can use a recursive function to help here:
def print_both_ways(start, end):
print(start)
if start != end:
print_both_ways(start+1, end)
print(start)
Usage:
print_both_ways(1,3) # prints 1,2,3,3,2,1 on separate lines

Related

Python: How to make numeric triangle with recursion

while I was working on the Python practice, I found a question that I cannot solve by myself.
The question is,
Input one integer(n), and then write the codes that make a triangle using 1 to 'n'. Use the following picture. You should make only one function, and call that function various times to solve the question. The following picture is the result that you should make in the codes.
Receive one integer as an argument, print the number from 1 to the integer received as a factor in a single line, and then print the line break character at the end. Once this function is called, only one line of output should be printed.
So by that question, I found that this is a question that requires the
recursion since I have to call your function only once.
I tried to work on the codes that I made many times, but I couldn't solve it.
global a
a = 1
def printLine(n):
global a
if (n == 0):
return
for i in range(1, a + 1):
print(i, end=" ")
print()
a += 1
for k in range(1, n+1):
print(k, end=" ")
print()
printLine(n - 1)
n = int(input())
printLine(n)
Then I wrote some codes to solve this question, but the ascending and descending part is kept overlapping. :(
What I need to do is to break two ascending and descending parts separately in one function, but I really cannot find how can I do that. So which part should I have to put the recursive function call?
Or is there another way can divide the ascending and descending part in the function?
Any ideas, comments, or solutions are appreciated.
Thx
You can use the below function:
def create_triangle(n, k: int = 1, output: list = []):
if n == 1:
output.append(n)
return output
elif k >= n:
output.append(" ".join([str(i) for i in range(1, n + 1)]))
return create_triangle(n - 1, k)
else:
output.append(" ".join([str(i) for i in range(1, n + 1)[:k]]))
return create_triangle(n, k + 1)
for i in create_triangle(5):
print(i)
Output:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
# function to print all the numbers from 1 to n with spaces
def printLine(k):
# create a range. if k is 4, will create the range: 1, 2, 3, 4
rng = range(1, k + 1)
# convert each number to string
str_rng = map(lambda x: str(x), rng)
# create one long string with spaces
full_line = " ".join(str_rng)
print(full_line)
# capture input
n = int(input())
# start from 1, and up to n, printing the first half of the triangle
for i in range(1, n):
printLine(i)
# now create the bottom part, by creating a descending range
for i in range(n, 0, -1):
printLine(i)
Using default parameter as a dict, you can manipulate it as your function variables, so in that way, you can have a variable in your function that keeps the current iteration you are at and if your function is ascending or descending.
def triangle_line(n, config={'max':1, 'ascending':True}):
print(*range(1, config['max'] + 1))
if config['ascending']:
config['max'] += 1
else:
config['max'] -= 1
if config['max'] > n:
config['ascending'] = False
config['max'] = n
elif config['max'] == 0:
config['ascending'] = True
config['max'] = 1
Each call you make will return one iteration.
>>> triangle_line(4)
1
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3 4
>>> triangle_line(4)
1 2 3
>>> triangle_line(4)
1 2
>>> triangle_line(4)
1
Or you can run on a loop, two times your input size.
>>> n = 4
>>> for i in range(0,n*2):
... triangle_line(n)
...
1
1 2
1 2 3
1 2 3 4
1 2 3 4
1 2 3
1 2
1

Recursive Pascals Triangle Layout

So i've managed to get Pascals Triangle to print successfully in terms of what numbers are printed, however, i can't get the formatting correct using:
n = int(input("Enter value of n: "))
def printPascal(n):
if n <= 0: #must be positive int
return "N must be greater than 0"
elif n == 1: #first row is 1, so if only 1 line is wanted, output always 1
return [[1]]
else:
next_row = [1] #each line begins with 1
outcome = printPascal(n-1)
prev_row = outcome[-1]
for i in range(len(prev_row)-1): #-1 from length as using index
next_row.append(prev_row[i] + prev_row[i+1])
next_row += [1]
outcome.append(next_row) #add result of next row to outcome to print
return outcome
print(printPascal(n))
this prints as:
Enter value of n: 6
[[1], [1, 1], [1, 2, 1], [1, 3, 3, 1], [1, 4, 6, 4, 1], [1, 5, 10, 10, 5, 1]
which is correct, however i want it to be formatted as a right angle triangle such as:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
my issue is, i'm new to this language and cannot work out where to put the splits and such in my code to be able to get it to print as this.
Any help or nudge in the right direction would be very much appreciated.
Thanks.
You want to use the str.join() function, which prints out all elements in a list separated by a string:
>>> L = printPascal(6)
>>> for row in L:
... print ' '.join(map(str, row))
...
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
' '.join(list) means you're printing out every element in a list separated by a space (' ').
However, every element in the list needs to be a string in order for the join function to work. Yours are integers. To fix this, I've changed all the integers to strings by doing map(str, row). This is equivalent to:
new_list = []
for item in row:
new_list.append(str(item))
Or as a list comprehension:
[str(item) for item in row]

Is there an easy way to get next and prev values in a for-loop?

So...is there an easy way to get next and previous values while iterating with a for-loop in Python?
I know this can be easily done if you do something like:
a = [3,4,5,6,3,4,5]
for x in range(len(a)):
next = a[x+1]
But what about:
for x in a:
x.next??
Here is a common pattern that I use to iterate over pairs of items in a sequence:
>>> a = range(10)
>>> for i, j in zip(a, a[1:]):
... print i, j
...
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
If you want three items (prev, item, next) you can do this:
>>> for i, j, k in zip(a, a[1:], a[2:]):
... print i, j, k
...
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
i is the previous element, j is the current element, k is the next element.
Of course, this "starts" at 1 and "ends" at 8. What should you receive as prev/next at the ends? Perhaps None? Probably easiest to just do this:
>>> a = [None] + a + [None]
>>> for i, j, k in zip(a, a[1:], a[2:]):
... print i, j, k
...
None 0 1
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 None
easiest way I know of is
for x,next in zip (a, a[1:]):
# now you have x and next available
You could always convert a into an iterator with iter and then iterate over that. This will allow you to use next inside the loop to advance the iterator that you are iterting over:
>>> a = [3,4,5,6,3,4,5]
>>> it = iter(a)
>>> for i in it:
... j = next(it, None)
... print('i={}, j={}'.format(i, j))
...
i=3, j=4
i=5, j=6
i=3, j=4
i=5, j=None
>>>
Also, the None in there is the default value to return if there is no next item. You can set it to whatever value you want though. Omitting the argument will cause a StopIteration exception to be raised:
>>> a = [1, 2, 3, 4, 5]
>>> it = iter(a)
>>> for i in it:
... j = next(it)
... print('i={}, j={}'.format(i, j))
...
i=1, j=2
i=3, j=4
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
StopIteration
>>>
If you want both the previous and the next element in a circular sequence for each iteration:
a = [3,4,5,6,3,4,5]
l = len(a)
for k, v in enumerate(a):
print a[(k-1)%l], v, a[(k+1)%l] #prints previous, current, next elements
this is easy too:
>>> a = [3,4,5,6,3,4,5]
>>> for i in range(1,len(a)):
... print a[i-1],a[i]
...
3 4
4 5
5 6
6 3
3 4
4 5
Probably overkill but I sometimes use the following more general generator for this, which yields a sequence of 'windows' of any size on a list or other iterable. (The window size must be less than the length of the iterable.)
def sliding_window(iterable, size):
try: # indexed iterable
for i in range(len(iterable) - size + 1):
yield iterable[i:i+size]
except TypeError: # iterator
window = [next(iterable) for _ in range(size)]
yield window
for item in iterable:
window = window[1:] + [item]
yield window
a = [3,4,5,6,3,4,5]
for current, following in sliding_window(a, 2):
print(current, following)

range() function is giving me trouble

If I were to type something like this, I would get these values:
print range(1,10)
[1,2,3,4,5,6,7,8,9]
but say if I want to use this same value in a for loop then it would instead start at 0, an example of what I mean:
for r in range(1,10):
for c in range(r):
print c,
print ""
The Output is this:
0
0 1
0 1 2
0 1 2 3
0 1 2 3 4
0 1 2 3 4 5
0 1 2 3 4 5 6
0 1 2 3 4 5 6 7
0 1 2 3 4 5 6 7 8
Why is 0 here? shouldn't it start at 1 and end in 9?
You are creating a second range() object in your loop. The default start value is 0.
Each iteration you create a loop over range(r), meaning range from 0 to r, exclusive, to produce the output numbers. For range(1) that means you get a list with just [0] in it, for range(1) you get [0, 1], etc.
If you wanted to produce ranges from 1 to r inclusive`, just add 1 to the number you actually print:
for r in range(1,10):
for c in range(r):
print c + 1,
print ""
or range from 1 to r + 1:
for r in range(1,10):
for c in range(1, r + 1):
print c,
print ""
Both produce your expected output:
>>> for r in range(1,10):
... for c in range(r):
... print c + 1,
... print ""
...
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
>>> for r in range(1,10):
... for c in range(1, r + 1):
... print c,
... print ""
...
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
1 2 3 4 5 6
1 2 3 4 5 6 7
1 2 3 4 5 6 7 8
1 2 3 4 5 6 7 8 9
If you pass only one argument to range function, it would treat that as the ending value (without including it), starting from zero.
If you pass two arguments to the range function, it would treat the first value as the starting value and the second value as the ending value (without including it).
If you pass three arguments to the range function, it would treat the first value as the starting value and the second value as the ending value (without including it) and the third value as the step value.
You can confirm this with few trial runs like this
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Default start value 0
>>> range(5, 10)
[5, 6, 7, 8, 9] # Starts from 5
>>> range(5, 10, 2)
[5, 7, 9] # Starts from 5 & takes only the 2nd element
Nope.
for r in range(1,10):
for c in range(r):
print c,
print ""
range(), when only given one argument, prints the numbers from 0 to the argument, not including the argument:
>>> range(6)
[0, 1, 2, 3, 4, 5]
And so, on the third iteration of your code, this is what happens:
for r in range(1,10): # r is 3
for c in range(r): # range(3) is [0,1,2]
print c, #you then print each of the range(3), giving the output you observe
print ""
https://docs.python.org/2/library/functions.html#range
From the docs:
The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0.

print matrix with indicies python

I have a matrix in Python defined like this:
matrix = [['A']*4 for i in range(4)]
How do I print it in the following format:
0 1 2 3
0 A A A A
1 A A A A
2 A A A A
3 A A A A
>>> for i, row in enumerate(matrix):
... print i, ' '.join(row)
...
0 A A A A
1 A A A A
2 A A A A
3 A A A A
I guess you'll find out how to print out the first line :)
Something like this:
>>> matrix = [['A'] * 4 for i in range(4)]
>>> def solve(mat):
print " ", " ".join([str(x) for x in xrange(len(mat))])
for i, x in enumerate(mat):
print i, " ".join(x) # or " ".join([str(y) for y in x]) if elements are not string
...
>>> solve(matrix)
0 1 2 3
0 A A A A
1 A A A A
2 A A A A
3 A A A A
>>> matrix = [['A'] * 5 for i in range(5)]
>>> solve(matrix)
0 1 2 3 4
0 A A A A A
1 A A A A A
2 A A A A A
3 A A A A A
4 A A A A A
This function matches your exact output.
>>> def printMatrix(testMatrix):
print ' ',
for i in range(len(testMatrix[1])): # Make it work with non square matrices.
print i,
print
for i, element in enumerate(testMatrix):
print i, ' '.join(element)
>>> matrix = [['A']*4 for i in range(4)]
>>> printMatrix(matrix)
0 1 2 3
0 A A A A
1 A A A A
2 A A A A
3 A A A A
>>> matrix = [['A']*6 for i in range(4)]
>>> printMatrix(matrix)
0 1 2 3 4 5
0 A A A A A A
1 A A A A A A
2 A A A A A A
3 A A A A A A
To check for single length elements and put an & in place of elements with length > 1, you could put a check in the list comprehension, the code would change as follows.
>>> def printMatrix2(testMatrix):
print ' ',
for i in range(len(testmatrix[1])):
print i,
print
for i, element in enumerate(testMatrix):
print i, ' '.join([elem if len(elem) == 1 else '&' for elem in element])
>>> matrix = [['A']*6 for i in range(4)]
>>> matrix[1][1] = 'AB'
>>> printMatrix(matrix)
0 1 2 3 4 5
0 A A A A A A
1 A AB A A A A
2 A A A A A A
3 A A A A A A
>>> printMatrix2(matrix)
0 1 2 3 4 5
0 A A A A A A
1 A & A A A A
2 A A A A A A
3 A A A A A A
a=[["A" for i in range(4)] for j in range(4)]
for i in range(len(a)):
print()
for j in a[i]:
print("%c "%j,end='')
it will print like this:
A A A A
A A A A
A A A A
A A A A
Use pandas for showing any matrix with indices:
>>> import pandas as pd
>>> pd.DataFrame(matrix)
0 1 2 3
0 A A A A
1 A A A A
2 A A A A
3 A A A A

Categories

Resources