Recursive one liner function to print numbers from N to 1 [duplicate] - python

This question already has answers here:
Can a lambda function call itself recursively in Python?
(16 answers)
Closed 2 years ago.
def recur(n):
print(n)
if n>1:
recur(n-1)
How can this be converted to just line. I can not find a way to use the logic as
recur = lambda x: print(x) if.......
I can not even use
func = lambda x: [print(i) for i in range(x,0,-1)]

If you want the numbers printed on the same line, you can use the end= parameter of the print function:
printDown = lambda n: print(n,end=" ") or printDown(n-1) if n>1 else print(n)
printDown(10)
10 9 8 7 6 5 4 3 2 1
If you want them on separate lines:
printDown = lambda n: print(n) or (printDown(n-1) if n>1 else None)
printDown(10)
10
9
8
7
6
5
4
3
2
1

One possible recursive lambda:
recur = lambda n: [print(n), recur if n>1 else lambda x: None][1](n-1)
recur(10)
Prints:
10
9
8
7
6
5
4
3
2
1

In Python >= 3.8, you can do it in one line entirely:
print(*(x := lambda n: [n]+x(n-1) if n else [])(10), sep='\n')
10
9
8
7
6
5
4
3
2
1
Note that this also does not abuse a comprehension or expression for side effects. x can still be used to create a common list now:
x(5)
# [5, 4, 3, 2, 1]

Related

Why it removes certain items from the list? [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 2 years ago.
I am new to python and i was just writing a programm to get an input like :
1 2 3 4 5 6 7 8 9
I wanted to remove the integers which are bigger than 2 and this was my code:
a = input()
b =a.split()
for i in range(len(b)):
b[i] = int(b[i])
for i in b:
if i >=3:
b.remove(i)
print(b)
I expected an output like this :
[1,2]
but when I run it,it shows this :
[1, 2, 4, 6, 8]
Can someone tell me ,where I made mistake?
Check with below code:
#a = '1 2 3 4 5 6 7 8 9'
a = input()
b =a.split()
for i in range(len(b)):
b[i] = int(b[i])
tempB = []
for i in b:
if i < 3:
tempB.append(i)
print(tempB)
More optimized and shortcode:
b =list(map(int,input().split()))
tempB = [i for i in b if i < 3]
print(tempB)

How to print i till its less than k while k is decreasing every iteration? [duplicate]

This question already has answers here:
Scope of python variable in for loop
(10 answers)
Closed 3 years ago.
I want to print i and k till i is less than or equal to k.
in C++ the code can be given as:
for(i=0;i<k;i++){
cout<<i<<k;
k--;
}
I am not getting the correct output.
this is my code
k=5
for i in range(k):
print(i,k)
k-=1
the output i get is:
0 5
1 4
2 3
3 2
4 1
but i want to get:
0 5
1 4
2 3
is there someway to use the range() function for this?
For loops in Python are really for-each and suboptimal for your needs. Use while instead:
i = 0; k = 5
while i < k:
print(i,k)
i += 1
k -= 1
k=5
for i in range(k):
print(i,k)
if k<=i:
break
k-=1

Trouble in swapping and assignment min and max elements

IMPORTANT UPD AT THE END!
The existing code works not for all cases.
def myfunc(x):
a = [int(i) for i in x.split()]
a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
a = [str(i) for i in a]
return ' '.join(a)
myfunc()
It works for 3 4 5 2 1 and don't work for 1 5 4 3 2.
Why?
!!!UPD: I made some changes and it looks very strange.
I used two different lines separately (with commented one of them). The program gives different results in some cases. BUT THE MOST INTERESTING, when I used two of them, uncommented - the program don't return the income string?
# a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
a[a.index(max(a))], a[a.index(min(a))] = a[a.index(min(a))], a[a.index(max(a))]
Cases which I use:
#print(myfunc("5 1 4 3 2"))
#print(myfunc("1 5 4 3 2"))
#print(myfunc("3 4 5 2 1"))
#print(myfunc("-30000 30000"))
#print(myfunc("2147483647 -2147483648"))
#print(myfunc("1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 17 16 15 14"))
#print(myfunc("1 2 3 4 5 6 7 8 9 10"))
#print(myfunc("1 9 8 7 6 5 4 3 2 10"))
UPD+=1 Guys I changed code to:
minind = a.index(min(a))
maxind = a.index(max(a))
a[minind], a[maxind] = a[maxind], a[minind]
Now it works for all case. But question about previous cases are still open
Please help. I spend about 2 hours in tries to find some explanation of this...
Please help
The reason it doesn't work is because the assignments are being executed sequentially. When you write:
a[a.index(min(a))], a[a.index(max(a))] = a[a.index(max(a))], a[a.index(min(a))]
it's essentially equivalent to:
tempmax, tempmin = a[a.index(max(a))], a[a.index(min(a))]
a[a.index(min(a))] = tempmax
a[a.index(max(a))] = tempmin
But notice that after doing the tempmax assignment, a.index(max(a)) can change. index() returns the earliest index, so if the minimum element was before the maximum element, this will now return the original minimum element's location (because it now contains the maximum element), and assigns tempmin back to it.
Your code assumes that the indexes to be assigned are computed before any of the assignments are done, but that's not how it actually works.
Your code doesn't work if the minimum is located before the maximum.
For example:
s = "1 5 4 3 2" # this doesn't work
myfunc(s)
>>> '1 5 4 3 2'
s = "5 1 4 3 2" # this works
myfunc(s)
>>> '1 5 4 3 2'
But, as you noticed, if you define indices before swapping, everything works fine.
def myfunc(x):
a = [int(i) for i in x.split()]
mn = a.index(min(a))
mx = a.index(max(a))
a[mn], a[mx] = a[mx], a[mn]
a = [str(i) for i in a]
return ' '.join(a)
s = "1 5 4 3 2"
myfunc(s)
>>> '5 1 4 3 2'
I'm waiting for some illuminati mind to have an answer for this.

What's the cleanest way to print an equally-spaced list in python?

Please close if this is a duplicate, but this answer does not answer my question as I would like to print a list, not elements from a list.
For example, the below does not work:
mylist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(%3s % mylist)
Desired output:
[ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15]
Basically, if all items in the list are n digits or less, equal spacing would give each item n+1 spots in the printout. Like setw in c++. Assume n is known.
If I have missed a similar SO question, feel free to vote to close.
You can exploit formatting as in the example below. If you really need the square braces then you will have to fiddle a bit
lst = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
frmt = "{:>3}"*len(lst)
print(frmt.format(*lst))
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
items=range(10)
''.join(f'{x:3}' for x in items)
' 0 1 2 3 4 5 6 7 8 9'
If none of the other answers work, try this code:
output = ''
space = ''
output += str(list[0])
for spacecount in range(spacing):
space += spacecharacter
for listnum in range(1, len(list)):
output += space
output += str(list[listnum])
print(output)
I think this is the best yet, as it allows you to manipulate list as you wish. even numerically.
mylist = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
print(*map(lambda x: str(x)+" ",a))

Python: print without overwriting printed lines

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

Categories

Resources