Python generate combinations of N in class K - python

I have this code
def array_combos(n,k):
arCombos = []
i = 0
a = [0]*k
while i > -1:
for j in range(i+1, k):
a[j] = a[j-1]+1
i=j
print(a)
arCombos.append(a)
while a[i] == i + n - k:
i -= 1
a[i] += 1
return arCombos
The print(a) print right values but list that function return is popolate by one single array n times.
If I use yield insted of popolate list function work perfectly.
Can we help?
Tks

The arCombos.append(a) always append the same, and only, instance of a, so you save it to the main arCombos multiple times, but there is still one instance that keep being modified.
Pass a copy of it with code like, more at Get a copy of list
arCombos.append(a[:])
arCombos.append(list(a))

Related

How to Reverse an array in groups in python?

I am trying to reverse the array in groups but I am getting this error:
:---- for i in arr: TypeError: 'NoneType' object is not iterable.
What's wrong with my code?
def reverseSubarray(arr,n,k):
if k == 1:
return
i = 0
while i < n:
l = i
r = min(i+k-1, n-1)
while l < r:
temp = arr[l]
arr[l] = arr[r]
arr[r] = temp
l += 1
r -= 1
i += k
return arr
def main():
n = int(input().strip())
string = input().strip().split()
arr=[]
for j in string:
arr.append(int(j.strip()))
k=int(input().strip())
arr = reverseSubarray(arr,n,k)
for i in arr:
print(i,end=' ')
if __name__ == "__main__":
main()
So the problem is that you're actually returning None. This happens because most likely you're giving k=1 so it will go to that line where you return nothing, which will return this error when trying to iterate.
You can treat the problem with a try-catch block on arr=reverseSubarray(arr,n,k) that will return a message like k cannot be 1
You can reverse an array in groups in python as given below,
def reverseSubarray(arr, N, K):
for i in range(0, len(arr),K):
l=arr[i:i+K]
l.reverse()
arr[i:i+K] =l
return arr
While your error was indeed coming from the fact that your function is returning None as other answers have pointed out, you have also written the function in a very non-pythonic style. Here is an example of how you could rewrite it more succintly:
def reverseInGroups(self, arr, N, K):
for i in range(0, N, K):
arr[i:i+K] = reversed(arr[i:i+K])
return arr
range(0, N, K) will return an iterator that goes from 0 to N-1 in steps of K. In other word, i will successively have value: 0, K, 2K, 3K, 4K, etc. until the last multiple of K that is less than N. Here is the documentation for more details.
arr[i:i+K] will refer to the slice of arr between indices i and i+K-1 or, put another way, [arr[i], arr[i+1], arr[i+2], ..., arr[i+K-1]]. It stops at i+K-1 so that you can naturally use arr[i:i+K] and arr[i+K:] without counting arr[i+K] twice.
reversed... reverses an iterator. Here's the doc.

(python) Can you please tell me what is the problem in the code below

I just start to learn python and i have a problem:
arr = [1,3,3,3,0,1,1]
def solution(arr):
a=[]
for r in range(len(arr)-1):
if arr[r] == arr[r+1]:
a.append(r+1)
print(a)
for i in range(len(a)):
k = int(a[i])
arr[k] = -1
arr.remove(-1)
return arr
There's a message
IndexError: list index out of range for ''arr[k] = -1''
Can you please tell me the reason for the Error and correct it?
Of course, it results in a Runtime exception. The list a stores indices. For each element v in a, you are trying to remove the value arr[v]. Doing this will reduce the size of arr by one every time. So, in the next iteration, v can be greater than the size of arr. Hence, it results in List index out of bound exception.
Your code, corrected:
arr = [1,3,3,3,0,1,1]
def solution(arr):
a=[]
for r in range(len(arr)-1):
if arr[r] == arr[r+1]:
a.append(r+1)
print(a)
c = 0
for i in range(len(a)):
k = int(a[i])
arr[k - c] = -1
arr.remove(-1)
c += 1
return arr
print(solution(arr))
It looks like you are trying to remove consecutive duplicates from the list. This can be easily solved using the following code.
def remove_duplicates(arr):
stack = [arr[0]]
for i in range(1, len(arr)):
if stack[-1] != arr[i]:
stack.append(arr[i])
return stack
print(remove_duplicates([1,3,3,3,0,1,1]))
In short, you cannot modify the array shape when you have determined the indices based on the unmodified array to index into it.
Here is something that you might be looking for:
def solution(arr):
a = []
for r in range(len(arr) - 1):
if arr[r] == arr[r + 1]:
a.append(r + 1)
print(a)
for i in range(len(a)):
k = int(a[i])
arr[k] = -1
# In the following line, you cannot modify the array length
# when you have already computed the indices based on the unmodified array
# arr.remove(-1)
arr = [x for x in arr if x != -1] # This is a better way to deal with it
return arr
print(solution(arr=[1, 3, 3, 3, 0, 1, 1]))
You don’t want to mess with the original list. Otherwise you’ll run into index errors. Index errors mean the item you were looking for in the list no longer exists. Most likely this line was the culprit arr.remove(-1).
arr = [1,3,3,3,0,1,1]
solution = []
for i, v in enumerate(arr):
if i == 0 or v != arr[i -1]:
solution.append(v)
print(solution)
This should get you what you are after. enumerate tells you want index you are at when looping through the list. More information can be found here: https://realpython.com/python-enumerate/
Well, you've probably already know what wrong happened here, removing the element inside the loop:
for i in range(len(a)):
k = int(a[i])
arr[k] = -1
arr.remove(-1)
You can fix the whole thing just changing the line to this list filter+lambda implementation, well, not inside the loop, but after the completion of loop iterations, just like follows:
for i in range(len(a)):
k = int(a[i])
arr[k] = -1
arr = list(filter(lambda x: x != -1, arr))
And you'll get what you want just from your solution!

How can I reduce the number of variables on the bubble sorting?

I made a bubble sort code. It works fine but I want to reduce the number of variables. I would like to use only i in the code. How can I remove j?
def bubble(v):
l = len(v)
for i in range(l-1):
for j in range(l-i-1):
if v[j]>v[j+1]:
v[j+1],v[j] = v[j],v[j+1]
return v
One of the possible ways is to use a list of length two, one for storing i and the other for storing j, in this fashion:
def bubble(v):
l = len(v)
i = [0, 0] # use like [i, j]
while i[0] < (l-1):
i[1] = 0
while i[1] < (l-i[0]-1):
if v[i[1]]>v[i[1]+1]:
v[i[1]+1],v[i[1]] = v[i[1]],v[i[1]+1]
i[1] += 1
return v
i[0] += 1
Note that, here, we have to use while loops instead of for loops.

Pass by value or reference with recursion implementing Heap Sort

I am attempting to implement heap sort using the psuedo code from the book Intro to Algorithms. The following is what I have:
def parent(i):
return i/2
def left(i):
return 2*i
def right(i):
return 2*i+1
def max_heapify(seq, i, n):
l = left(i)
r = right(i)
if l <= n and seq[n] > seq[i]:
largest = l
else:
largest = i
if r <= n and seq[r] > seq[largest]:
largest = r
if largest != i:
seq[i], seq[largest] = seq[largest], seq[i]
max_heapify(seq, largest, n)
def heap_length(seq):
return len(seq) - 1
def build_heap(seq):
n = heap_length(seq)
for i in range(n/2,0,-1):
max_heapify(seq, i, n)
def sort(seq):
build_heap(seq)
heap_size = heap_length(seq)
for i in range(heap_size,1,-1):
seq[1], seq[i] = seq[i], seq[1]
heap_size = heap_size - 1
max_heapify(seq, 1, heap_size)
return seq
I am having issues with understanding passing by value or by reference in Python. I have looked at the following question and it seems that I am passing the list by value. My questions is how to return the correctly sorted list either by reference or by value?
arrays are always passed by reference
if you want to pass by value use slice
my_func(my_array[:]) #send copy
my_func(my_array) #array is modified inside and changes are reflected in original

python recursive pascal triangle

After completing an assignment to create pascal's triangle using an iterative function, I have attempted to recreate it using a recursive function. I have gotten to the point where I can get it to produce the individual row corresponding to the number passed in as an argument. But several attempts to have it produce the entire triangle up to and including that row have failed. I even tried writing a separate function which iterates over the range of the input number and calls the recursive function with the iterated digit while appending the individual lines to list before returning that list. The desired output should be a list of lists where each internal list contains one row of the triangle. Like so:
[[1], [1, 1], [1, 2, 1]...]
Instead it returns a jumbled mess of a nested list completely filled with 1's.
Here is the recursive function in question, without the second function to append the rows (I really wanted 1 all inclusive function anyway):
def triangle(n):
if n == 0:
return []
elif n == 1:
return [1]
else:
new_row = [1]
last_row = triangle(n-1)
for i in range(len(last_row)-1):
new_row.append(last_row[i] + last_row[i+1])
new_row += [1]
return new_row
To be clear, I have already completed the assigned task, this is just to provide a deeper understanding of recursion...
Iterative solution:
def triangle(n):
result = []
for row in range(n):
newrow = [1]
for col in range(1, row+1):
newcell = newrow[col-1] * float(row+1-col)/col
newrow.append(int(newcell))
result.append(newrow)
return result
You just need to pass a list of lists through the recursion, and pick off the last element of the list (i.e. the last row of the triangle) to build your new row. Like so:
def triangle(n):
if n == 0:
return []
elif n == 1:
return [[1]]
else:
new_row = [1]
result = triangle(n-1)
last_row = result[-1]
for i in range(len(last_row)-1):
new_row.append(last_row[i] + last_row[i+1])
new_row += [1]
result.append(new_row)
return result
An alternative to happydave's solution, using tail recursion:
def triangle(n, lol=None):
if lol is None: lol = [[1]]
if n == 1:
return lol
else:
prev_row = lol[-1]
new_row = [1] + [sum(i) for i in zip(prev_row, prev_row[1:])] + [1]
return triangle(n - 1, lol + [new_row])
I think its shod be helpful, this code draw triangle and do it recursively:
def traingle(n):
if n == 1:
print(1)
return [1]
else:
answer = [1]
print_able = '1 '
previos = traingle(n-1)
for index in range(len(previos)-1):
eleman = previos[index]+previos[index+1]
answer.append(eleman)
print_able += str(eleman)+' '
answer.append(1)
print_able += '1'
print(print_able)
return answer
end = int(input())
traingle(end)
Yes, as Karl Knechtel also showed, recursive Pascal Triangle can go this way :
P=lambda h:(lambda x:x+[[x+y for x,y in zip(x[-1]+[0],[0]+x[-1])]])(P(h-1))if h>1 else[[1]]
print(P(10))

Categories

Resources