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])
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]
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.
Say I have an array with longitudes, lonPorts
lonPort =np.loadtxt('LongPorts.txt',delimiter=',')
for example:
lonPort=[0,1,2,3,...]
And I want to repeat each element a different amount of times. How do I do this? This is what I tried:
Repeat =[5, 3, 2, 3,...]
lonPort1=[]
for i in range (0,len(lenDates)):
lonPort1[sum(Repeat[0:i])]=np.tile(lonPort[i],Repeat[i])
So the result would be:
lonPort1=[0,0,0,0,0,1,1,1,2,2,3,3,3,...]
The error I get is:
list assignment index out of range
How do I get rid of the error and make my array?
Thank you!
You can use np.repeat():
np.repeat(a, [5,3,2,3])
Example:
In [3]: a = np.array([0,1,2,3])
In [4]: np.repeat(a, [5,3,2,3])
Out[4]: array([0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3])
Without relying on numpy, you can create a generator that will consume your items one by one, and repeat them the desired amount of time.
x = [0, 1, 2, 3]
repeat = [4, 3, 2, 1]
def repeat_items(x, repeat):
for item, r in zip(x, repeat):
while r > 0:
yield item
r -= 1
for value in repeat_items(x, repeat):
print(value, end=' ')
displays 0 0 0 0 1 1 1 2 2 3.
Providing a numpy-free solution for future readers that might want to use lists.
>>> lst = [0,1,2,3]
>>> repeat = [5, 3, 2, 3]
>>> [x for sub in ([x]*y for x,y in zip(lst, repeat)) for x in sub]
[0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3]
If lst contains mutable objects, be aware of the pitfalls of sequence multiplication for sequences holding mutable elements.
I tried to figure out the following problem through list comprehension but I couldn't make it work. I will show you how I solved the problem using a loop and a list comprehension.
So, I have a list that can have 0 to 6 elements in a range(6) and when I apply my function on it I want to change the values, as shown here:
l = [0, 1, 2, 3, 4, 5]
mirror = [5, 4, 3, 2, 1, 0]
I don't want to just rotate the array by 180 degrees but I actually want to replace the values. For example, my list looks like this now:
l = [2, 5]
Then l_inverted list should look like this:
l_inverted = [3, 0]
I came up with a regular way to solve it but ever since I started learning Python I've preferred list comprehensions.
l = [0, 3, 5]
mirror = [5, 4, 3, 2, 1, 0]
i = 0
for element in l:
l[i] = mirror[element]
i += 1
This actually inverts the l list. Here's my approach using a list comprehension:
l = [3, 5]
mirror = [5, 4, 3, 2, 1, 0]
for element in l:
print(element)
l = [mirror[element] if x==element else x for x in l]
This works fine.
Until:
l = [0, 3, 5]
mirror = [5, 4, 3, 2, 1, 0]
for element in l:
print(element)
l = [mirror[element] if x==element else x for x in l]
So it will replace 5 with 0, 2 with 3 and both 5s (the new one too) become 0. Obviously, I don't want it like that.
Should I stick to the working solution or is there a smooth way to solve it with list comprehensions? I'm trying to practice list comprehensions at all times but it's not fully in my brain yet. Thanks a lot.
If you want it as a list comprehension:
>> l = [0, 3, 5]
>> mirror = [5, 4, 3, 2, 1, 0]
>> l_inverted = [mirror[x] for x in l]
>> l_inverted
[5, 2, 0]
You are drowning in a spoonful of water and trying to take us with you.
You are using bad naming conventions that make your simple problem complicated to comprehend.
orig = [0, 1, 2, 3, 4, 5]
orig_rev = l[::-1]
selector = [0, 3, 5]
result = [orig_rev[i] for i in selector]
print(result ) # [5, 2, 0]
Based on your first two examples, it seems you are looking for the complement of each list value according to some base, similar to ones' complement. You could either hard-code the base as 5 or whatever, or you could assume it's the maximum number in the list and calculate it. Here's a solution for the latter:
Concept
<this complement> = <max value in list> - <this value>
Code
values = [0, 3, 2, 4, 5]
max_value = max(values)
complements = [max_value - value for value in values]
print complements
Result
[5, 2, 3, 1, 0]
I have the list with some values, i want to exclude not the values from my list and replace them with 0.
That is pseudocode:
for i in range(0,img.shape[0]):
for j in range(0,img.shape[1]):
if img[i][j]!=[some values]:
img[i][j]=0
Here is one way to do it:
In [1]: l = [1, 2, 1, 10, 2, 1, 3, 10]
In [2]: exclusions = [1, 2]
In [3]: [el if el not in exclusions else 0 for el in l]
Out[3]: [0, 0, 0, 10, 0, 0, 3, 10]
Depending on the size of exclusions, the code might be more performant if you turned it into a set.