recursive calling to print list of numbers - python

I'm trying to sort an array and print the output recursively until the array is = [0,0,0,0,0] but it only prints [3,2,1,0,0] ,,,,, this is what i wrote can you help to fix this isuee ,, still learning
the answer should be
[4 3 2 1 0 0]
[3 2 1 0 0 0]
[2 1 0 0 0 0]
[1 0 0 0 0 0]
[0 0 0 0 0 0]
numbers=[5,4,3,2,1,1]
numbers.sort()
numbers.sort(reverse=True)
print('List sorted: ', numbers)
def list_arrays(numb):
level=numbers[0]
if len(numbers)-1 < level:
return 0
else:
numbers.pop(0);
print(numbers)
for i in range(len(numbers)):
numbers[i] -= 1
print(numbers)
#list_arrays(numbers)
if __name__=='__main__':
list_arrays(numbers)

You have a number of problems here. First, you defined a function, but you never called the function. That's why nothing printed.
Second, you don't need "sort" immediately followed by "sort(reverse)".
Third, I don't know what you were attempting by checking the level. That doesn't seem to be related to your problem.
Fourth, you're subtracting 1 from every number, but you should only be subtracting 1 if the number is greater than 0.
Finally, you're only subtracting once. You need to repeat it until all the numbers are zero.
numbers=[5,4,3,2,1,1]
numbers.sort(reverse=True)
print('List sorted: ', numbers)
def list_arrays(numb):
while any(numb):
for i in range(len(numb)):
if numb[i]:
numb[i] -= 1
print(numb)
list_arrays(numbers)
In most cases, rather than modify the list in place, I would suggest creating a new list during each loop, but for this simple assignment, this will work.
To remove the zeros, you really do want to create a new list, not modify in place.
numbers=[5,4,3,2,1,1]
numbers.sort(reverse=True)
print('List sorted: ', numbers)
def list_arrays(numb):
while numb:
new = []
for v in numb:
if v > 1:
new.append(v-1)
numb = new
print(numb)
list_arrays(numbers)
Or even:
numbers=[5,4,3,2,1,1]
numbers.sort(reverse=True)
print('List sorted: ', numbers)
def list_arrays(numb):
while numb:
numb = [v-1 for v in numb if v>1]
print(numb)
list_arrays(numbers)

In another comment you asked to remove all zeroes. Perhaps this is the solution you are looking for -
def run(t):
while(t):
yield t
t = [x - 1 for x in t if x > 1]
mylist = [5,4,3,2,1,1]
for t in run(mylist):
print(t)
[5, 4, 3, 2, 1, 1]
[4, 3, 2, 1]
[3, 2, 1]
[2, 1]
[1]
Or gather all lines in a single array using list -
mylist = [5,4,3,2,1,1]
print(list(run(mylist)))
[
[5, 4, 3, 2, 1, 1],
[4, 3, 2, 1],
[3, 2, 1],
[2, 1],
[1]
]

Maybe this is what you want?
def make_all_zero_and_print(numbers):
while numbers[0] > 0:
print(numbers)
for i in range(len(numbers)):
if numbers[i] > 0:
numbers[i] -= 1
print(numbers)
make_all_zero_and_print([5, 4, 3, 2, 1, 1])
Output:
[5, 4, 3, 2, 1, 1]
[4, 3, 2, 1, 0, 0]
[3, 2, 1, 0, 0, 0]
[2, 1, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0]

Related

I have problem with removing last item from list [duplicate]

This question already has answers here:
How to remove items from a list while iterating?
(25 answers)
Closed 1 year ago.
nums = [0,1,2,2,3,0,4,2]
val = 2
for i in nums:
if i == val:
nums.remove(i)
else:
continue
print(nums)
Result is [0,1,3,0,4,2] instead of [0,1,3,0,4]
Well maybe I am a little bit confused because in the title you ask for removing just the last item but in the question you ask for an expected result. I just took your code and make it work to get the expected output with a list comprehension. It looks like this:
nums_new = [i for i in nums if i != val]
You can ofcourse name nums_new to only nums.
Your mistake becomes clear if you print your data inside the loop:
nums = [0,1,2,2,3,0,4,2]
val = 2
for i in nums:
if i == val:
nums.remove(i)
print(i, nums)
print(nums)
Output:
0 [0, 1, 2, 2, 3, 0, 4, 2]
1 [0, 1, 2, 2, 3, 0, 4, 2]
2 [0, 1, 2, 3, 0, 4, 2]
3 [0, 1, 2, 3, 0, 4, 2]
0 [0, 1, 2, 3, 0, 4, 2]
4 [0, 1, 2, 3, 0, 4, 2]
2 [0, 1, 3, 0, 4, 2]
[0, 1, 3, 0, 4, 2]
Note:
i goes through 0, 1, 2, 3, ..., i.e., not two 2s in a row. That's because you remove the first 2, but "the loop" doesn't care, it still goes to the next position in the list, which then holds the value 3.
You do find the 2 at the end, but since remove removes the first occurrence, it removes the earlier 2.
You have a few options:
Filter
your_list = [1, 2, 3, 4, 2, 3, 4, 2]
filtered_values = filter(lambda value: value != 2, your_list)
The first argument is the filtering function, the second is your values - whatever evaluates to False is removed from the list.
List comprehension
your_list = [1, 2, 3, 4, 2, 3, 4, 2]
filtered_values = [value for value in your_list if value != 2]
There are many other ways of doing it, although those are the most common ways of doing it.
You can also do this with the NumPy module:
import numpy as np
# generate 20 random integers between 0 (inclusive) and 5 (exclusive)
myarr = np.random.randint(0, 5, 20)
print(myarr)
[0 2 0 1 2 0 3 0 0 0 3 4 1 3 1 4 1 0 4 4]
val = 2
myarr = np.delete(myarr, np.where(myarr == val))
print(myarr)
[0 0 1 0 3 0 0 0 3 4 1 3 1 4 1 0 4 4]
myarr = np.delete(myarr, np.where(myarr == val))
In that line we do the following: from the array myarr, delete the elements whenever that element equals val.
The same can be achieved with your initial list, by first converting it to a numpy array:
nums = np.array(nums)

Move Zeroes to the end of the string

I was just doing some leetcode
but this blew my mind.
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
nums = [0, 1, 0, 3 ,12]
k = 0
i=0
while i < len(nums):
print(i)
if nums[i] == 0:
print('inside if=',i)
print('before',nums)
k += 1
print('removed',nums[i])
nums.remove(i)
print('after',nums)
else:
i += 1
print('no change',nums)
print('final',nums)
for j in range (k):
nums.append(0)
print(nums)
and the output is:
0
inside if= 0
before [0, 1, 0, 3, 12]
element to be removed 0
after [1, 0, 3, 12]
0
no change [1, 0, 3, 12]
->1
->inside if= 1
->before [1, 0, 3, 12]
->element to be removed 0
->after [0, 3, 12]
1
no change [0, 3, 12]
2
no change [0, 3, 12]
final [0, 3, 12]
[0, 3, 12, 0, 0]
How can it remove element 1 if it can read that it has to remove 0?
So I got to know my dumb mistake.
Actually remove() is used to remove the element that is mentioned.
Like if I type remove(6)from a list a = [1,2,3,4,5,6]. it removes element 6, not the element that is at 6th position.
so use pop() to do so.

Why the iteration variable changed without `return` or `yield` in Python3

I'm a newer to Python and I'm learning it.
Here I want to use a generator to output the Pascal's Triangle. I'd like to get the output like this
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
And what I wrote is
# Pascal's Triangle
def triangles() :
result = [1]
while True :
# if i use yield result, the output will be [1, 0], [1, 1, 0] ...
yield result[:]
result.append(0)
result = [result[i]+result[i-1] for i in range(len(result))]
# make a list of the triangles.
n = 0
results = []
for t in triangles():
results.append(t)
n = n + 1
if n == 5:
break
for t in results:
print(t)
This code works well. However when I change yield result[:] to yield result, the output is
[1, 0]
[1, 1, 0]
[1, 2, 1, 0]
[1, 3, 3, 1, 0]
[1, 4, 6, 4, 1]
After debugging the code, I found that the iteration variable t changed to [1, 0] after running
result.append(0)
the first time, but there isn't any words like return or yield.
Why could that happen?
Update Question
I made a minimal working example here
def func():
a = [1, 2]
while True :
yield a
a.append(0)
# # PM 1 (Print Method 1)
# n = 0
# results = []
# b = func()
# for t in b:
# results.append(t)
# n = n + 1
# if n == 3:
# break
# for t in results:
# print(t)
# PM 2
b = func()
counter = 0
for i in b :
print(i)
counter += 1
if counter == 3:
break
When I use PM 1 to print the list, I got
[1, 2, 0, 0]
[1, 2, 0, 0]
[1, 2, 0, 0]
When I use PM 2 to print the list, I got
[1, 2]
[1, 2, 0]
[1, 2, 0, 0]
So I think the problem occurs at how I print the list.
I am sure what is the direction of your work, whether it just for print or more. But, below should give you a general overview about tril_indices
import numpy as np
# Pascal's Triangle
def triangles() :
result = [1]
while True :
# if i use yield result, the output will be [1, 0], [1, 1, 0] ...
yield result[:]
result.append(0)
result = [result[i]+result[i-1] for i in range(len(result))]
# make a list of the triangles.
n = 0
results = []
for t in triangles():
results.extend(t)
n = n + 1
if n == 5:
break
res_arr=np.array(results)
t,b = np.tril_indices(6, -1)
idx_pair = np.tril_indices(6, -1)
this_con = np.zeros ( (6, 6) )
this_con [idx_pair] = res_arr
print(this_con)

Pushing items in a list in Python

Let's say there's a list of [0, 3, 14, 0] and i want to 'push' the items of that list to the right corner. So the list will become [0, 0, 3, 14]. So basically the items with value > 0 will ignore the 0s and replace its position. The number could be anything (except 0) so sorting won't do it. Couple of examples:
[0, 4, 0, 4] => [0, 0, 4, 4]
[1, 0, 2, 2] => [0, 1, 2, 2]
[13, 0, 0, 6] => [0, 0, 13, 6]
Is there an efficient solution to this? I have been racking my brain for hours and i've found nothing near a solution.
If you want an efficient solution that is not inplace, and faster than sorting, you can do this:
lst = [0,1,2,0]
helper = [0 for i in len(lst)]
counter = 0
for i in range(len(lst)-1,-1,-1):
if lst[i]:
helper[len(lst)-1-counter] = lst[i]
counter += 1
print(helper)
This is probably not the most efficient solution:
dst_lst = [n for n in lst if n <= 0] + [n for n in lst if n > 0]
This will traverse the original list twice and create two temporary and one final list.
Hope this example helps!
Here we are using Python pre-defined data type queue
>>> import queue
>>> t = queue.deque()
>>> for each in [0, 4, 0, 4]:
... if each <= 0: t.appendleft(each)
... else: t.append(each)
...
>>> t
deque([0, 0, 4, 4])

PYTHON: Doesn't increment position of a list element

sequence = [1, 1, 1, 2, 3]
sequence2 = []
k = 0
if len(sequence) == 2 or len(sequence) == 1:
print('Great!')
else:
for element in range(0, (len(sequence))):
sequence2.append(sequence[element])
sq = sequence2.index(sequence2[-1])
print(sequence2, sq)
if sequence2 == sorted(sequence2):
print('This is good thus far:', sequence2)
else:
print(sequence2[sq-1], sequence2[sq])
print(sequence2.index(sequence2[-1]))
if sequence2[sq-1] >= sequence2[sq]:
sequence2.pop(sequence2.index(sequence2[sq - 1]))
print('We poppoed an element')
print(sequence2)
k = k+1
if k >= 2:
print(sequence2)
print('This doesnt work')
else:
print('Works properly!')
OUTPUT:
[1] 0
This is good thus far: [1]
[1, 1] 0
This is good thus far: [1, 1]
[1, 1, 1] 0
This is good thus far: [1, 1, 1]
[1, 1, 1, 2] 3
This is good thus far: [1, 1, 1, 2]
[1, 1, 1, 2, 3] 4
This is good thus far: [1, 1, 1, 2, 3]
Works properly!
Hey guys; I've got a question why does the program gives me back 0 for sq, the first 3 times it iterates? Shouldn't it give me 0, 1, 2..? I can't wrap my head around it for the past 2 days...
Because sequence2.index(value) returns the first instance of 'value' , and you have repeated 1's in sequence2
Because you have 3 '1s' and it show the first if you tried with different data

Categories

Resources