Related
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]
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)
I was trying to solve the classic coin change problem with the aim of getting all the possible coin combinations which can be changed for a given value of money. Although dynamic programming will be most suitable for this, I am using recursions just to develop my understanding. I am trying to keep a record of the function's position in the recursion tree by continuously appending a list. However, I also need to remove elements from list when function travels from one brach to other. For this purpose, I have used while loop in the code, but instead of just the last two elements from the list, it is removing three elements. Any clarifications would be appreciated -
masterlst = []
lst =[]
def MakeTree (n, coins):
d = len(coins)
for item in coins:
print(item)
lst.append(item)
print(lst)
m = n - item
print(m)
if m > 0:
MakeTree(m,coins)
if m == 0:
global masterlst
masterlst.append(lst[:])
print(masterlst)
while lst[-1] == max(coins):
del lst[-1]
print(lst)
del lst[-1]
print(lst)
print('Done!')
output = MakeTree(6, (1,3,4))
print(output)
Terminal output is shown below -
[1]
5
1
[1, 1]
4
1
[1, 1, 1]
3
1
[1, 1, 1, 1]
2
1
[1, 1, 1, 1, 1]
1
1
[1, 1, 1, 1, 1, 1]
0
[[1, 1, 1, 1, 1, 1]]
[1, 1, 1, 1, 1]
Done!
3
[1, 1, 1, 1, 1, 3]
-2
[1, 1, 1, 1, 1]
Done!
4
[1, 1, 1, 1, 1, 4]
-3
[1, 1, 1, 1, 1]
[1, 1, 1, 1]
Done!
[1, 1, 1]
Done!
As shown above, after printing -3 (6th line from bottom), I am expecting only
[1, 1, 1, 1, 1]
[1, 1, 1, 1]
Done!
But program is going one step extra and producing
[1, 1, 1]
Done!
as well, which is not desired. I want to remove last two elements form the list as long as the last element is equal to max(coins) and remove only one otherwise.
I am new to python, so any other syntax improvement suggestion will also be helpful.
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)
I have a list with 24 million elements and I want to increment count of each element iteratively and store the count in another list in faster way. For example, my list is:
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
My expected output is
[1, 2, 1, 1, 2, 3, 1, 2, 1]
The code i used is
z=[]
for i in a:
z.append(a.count(i))
But my output is bit different
[2, 2, 1, 3, 3, 3, 2, 2, 1]
My order of this newly created list is also important and should be based on my list(a). Any help is really appreciated.
Based on your expected output, since you need the count of elements till that index of the list at which you are iterating at that point of time, the below code should work:
from collections import defaultdict
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
a_dict = defaultdict(int)
a_output = []
for x in a:
a_dict[x] += 1
a_output.append(a_dict[x])
print(a_output)
Output:
[1, 2, 1, 1, 2, 3, 1, 2, 1]
Here is one solution -
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
countArr = []
temp = {}
for i in a:
if i in temp:
temp[i]+=1
countArr.append(temp.get(i))
else:
temp[i] = 1
countArr.append(temp.get(i))
You could use a dictionary and a for loop to accomplish this:
counts = {}
a = ['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
z = []
for i in a:
if i in counts:
counts[i] += 1
else:
counts[i] = 1
z.append(counts[i])
print(z)
# [1, 2, 1, 1, 2, 3, 1, 2, 1]
You can also do this fun hacky thing with a list comprehension, which exploits the evaluation order of tuples and does essentially the same as the above for loop but condensed into one line:
counts = {}
z = [(counts.__setitem__(i, counts[i] + 1 if i in counts else 1), counts[i])[1] for i in a]
print(z)
# [1, 2, 1, 1, 2, 3, 1, 2, 1]
you can use sub-array count :
a=['bike','bike','jeep','horse','horse','horse','flight','flight','cycle']
z=[]
i = 0
while i < len(a):
#print(a[0:i])
#print(a[i])
z.append(a[0:i].count(a[i]) + 1)
i+= 1
print(z)