Python question on how these two lists are different? - python

I have a weird problem where I have 2 seemingly identical lists and yet using one gets one answer and using the other gets a second answer even though they are the same list, just generated by different methods.
try the program below and see that b and c are the same. (print outs on line 8)
then when using b's on line 11,13 and 16 we get an answer of 0.
using c's on line 11,13 and 16 we get an answer of 6.
i've tried this on numerous compliers and cannot understand what aspect python is using to differenciate from b and c. Try it yourself by copying and pasting below(Thanks in advance for helping out!):
def oddCells(n, m, indices):
a = [0]*m
b =[]
for every in range(n):
b +=[a]
c = [ [0] * m for i in range(n) ]
result = 0
print(b,"|",c,b == c)
for e in indices:
for i in range(m):
b[e[0]][i] += 1
for j in range(n):
b[j][e[1]] += 1
for i in range(n):
for j in range(m):
if b[i][j] %2 != 0:
result +=1
return(result)
W =[[0,1],[1,1]]
print(oddCells(2,3,W))
############SECOND VERSION TO COMPARE####################################
def oddCells(n, m, indices):
a = [0]*m
b =[]
for every in range(n):
b +=[a]
c = [ [0] * m for i in range(n) ]
result = 0
print(b,"|",c,b == c)
for e in indices:
for i in range(m):
c[e[0]][i] += 1
for j in range(n):
c[j][e[1]] += 1
for i in range(n):
for j in range(m):
if c[i][j] %2 != 0:
result +=1
return(result)
W =[[0,1],[1,1]]
print(oddCells(2,3,W))

Related

construct edit matrix for Levenshtein distance

To calculate Levenshtein distance, we always choose to use dynamic programming. For this, we will create an edit distance matrix as shown below:
enter image description here
Here is the code:
while True:
try:
a = input()
b = input()
board = [[0 for j in range(len(b)+1)] for i in range(len(a)+1)]
for i in range(len(a)+1):
board[i][0] = i
for j in range(len(b)+1):
board[0][j] = j
for i in range(1, len(a)+1):
for j in range(1, len(b)+1):
if a[i-1] == b[j-1]:
d = 0
else:
d = 1
board[i][j] = min(board[i-1][j]+1,
board[i][j-1]+1,
board[i-1][j-1]+d)
print(board[-1][-1])
except:
break
So my question is when we construct the matrix, why we need to add 1 to len(a) and len(b). Because as shown in the picture before, only the red part is the valid part in the matrix. So I modified my code:
while True:
try:
a = input()
b = input()
board = [[0 for j in range(len(b))] for i in range(len(a))]
for i in range(len(a)):
board[i][0] = i
for j in range(len(b)):
board[0][j] = j
for i in range(1, len(a)):
for j in range(1, len(b)):
if a[i] == b[j]:
d = 0
else:
d = 1
board[i][j] = min(board[i-1][j]+1,
board[i][j-1]+1,
board[i-1][j-1]+d)
print(board[-1][-1])
except:
break
I test this modified code and it still gives the correct answer in most tests. But when both strings are very long, the result will be 1 less. I am very confused about this. Maybe this question is stupid, but I still hope to be answered, thank you. 🙏
The problem with your solution is that you skip a[0] and b[0] case and you have to handle that case first. The original solution handles it with a[i-1] == b[j-1] when i = 1 and j = 1 but you don't

Why this Merge Sort does not work properly?

I need to implement Merge Sort using Python 3. I coded it. But It doesn't give proper output. Can anybody check it please?
Here my code is,
def mergeSort(A, p, r):
if p < r:
q = (p + r) // 2
mergeSort(A, p, q)
mergeSort(A, q+1, r)
Merge(A, p, q, r)
def Merge(A, p, q, r):
i = 1
j = q+1
k = 0
TEMP = [0] * (r+1)
while i <= q and j <= r:
if A[i] <= A[j]:
TEMP[k] = A[i]
k += 1
i += 1
else:
TEMP[k] = A[j]
k += 1
j += 1
if (j > r) :
for t in range(0, q-1):
A[r-t] = A[q-t]
for t in range(0, k-1):
A[p+t] = TEMP[t+1]
A = [15, 16, 13, 10, 19, 18]
mergeSort(A, 0, len(A)-1)
print(A)
Thank you
The way you perform merge looks weird (to me), but I will correct on what you have so far.
1- Initialization value of i is wrong, it should be:
i = p
because i is the first element you will look in array A.
2- Initialization value of size of TEMP array is wrong, it should be:
(r - p + 1)
3- There seems a mistake in filling in TEMP array and/or replacing A array elements, here is the fixed code. I wrote a comment about the part after first while loop to indicate what needs to be done at that point.
def mergeSort(A,p,r):
if p < r:
q = (p+r)//2
mergeSort(A,p,q)
mergeSort(A,q+1,r)
Merge(A,p,q,r)
def Merge(A,p,q,r):
i = p
j = q+1
k=0
TEMP = [0]*(r - p + 1)
while i <= q and j <= r:
if A[i] <= A[j]:
TEMP[k] = A[i]
k += 1
i += 1
else:
TEMP[k] = A[j]
k += 1
j += 1
"""
There are currently 2 cases
1- i > q, means we exhausted left but there are elements in the right
2- j > r, means we exhausted right but there are elements in the left
"""
if (j > r):
# copy elements at the left side to temp
while (i <= q):
TEMP[k] = A[i]
i += 1
k += 1
else:
# copy elements at the right side to temp
while (j <= r):
TEMP[k] = A[j]
j += 1
k += 1
# replace elements in A with elements in TEMP
for t in range(k):
A[p+t] = TEMP[t]
A = [15,16,13,10,19,18]
mergeSort(A,0,len(A)-1)
print(A)
The error lies in the Merge() function.
Initialisation of i=p and not i=1
After the while loop terminates, there's a chance that either i<q or j<r. We need to accommodate those cases as well.
Size of array TEMP was incorrect.
Corrected Merge Function:
def Merge(A,p,q,r):
i = p
j = q+1
k=0
TEMP = [0]*(r-p+1)
while i <= q and j <= r:
if A[i] <= A[j]:
TEMP[k] = A[i]
k += 1
i += 1
else:
TEMP[k] = A[j]
k += 1
j += 1
while i<=q:
TEMP[k] = A[i]
k+=1
i += 1
while j<=r:
TEMP[k] = A[j]
k+=1
j += 1
for t in range (p,r+1):
A[t] = TEMP[t-p]
Note: Please try using more meaningful variable names.

Python: What is wrong with the indexing logic in my code?

"You are given an array of n integers and an integer k. Find and print the number of (i,j) pairs where i<j and a[i] + a[j] is evenly divisible by k."
Sample input would be:
6 3
1 3 2 6 1 2
where 6 is n, 3 is k and the second line is the array of integers. The output for this input would be 5.
Here is my code, but i am not passing the test cases and am almost positive it has to do with how i am indexing it.
import sys
n,k = input().strip().split(' ')
n,k = [int(n),int(k)]
a = [int(a_temp) for a_temp in input().strip().split(' ')]
count=0;
for i in range(n):
curr = n-i
for j in range(curr):
if i < i + j:
if k % (a[i] + a[i+j]) ==0:
count = count + 1
print(count)
Also, followup question: Is this method i am approaching an efficient way of going about it?
you can try this ...
import sys
n,k = input().strip().split(' ')
n,k = [int(n),int(k)]
a = [int(a_temp) for a_temp in input().strip().split(' ')]
print(sum([1 for i in range(n) for j in range(i) if (a[i]+a[j])%k==0]))
k % ... means "k is divisible by ...", not "... is divisible by k".
if i < i + j is not very useful; you're better off doing what furas recommends in comments.
What you need is to make use of itertools.combinations:
from itertools import combinations
count = 0
for i, j in combinations(range(n), 2):
if i < j and (a[i] + a[j]) % k == 0:
print i, j
count += 1
Discussion
range(n) returns a list of indices 0 .. n-1
combinations(range(n), 2) will yield a list of two indices (without duplications)
(a[i] + a[j]) % k == 0 is the test that your asked
Note that combinations will yield pairs of i, j where i is always less than j, but the test i < j is there as a paranoid measure

Solution to splitting array into equal subarrays too slow

I'm having trouble with a dynamic programming problem. I have tested my solution against test cases, and it is correct. However, it is too slow. This leads me to believe that I may not be caching the solutions to subproblems effectively. Here is the problem statement:
There is an array A that contains N numbers. Given an array, a player can split the array into two non-empty subarrays only if the elements in each subarray sum to the same value. After a split is made, the player discards one subarray and is allowed to continue splitting on the remaining subarray. This continues until a split is no longer possible. What is the maximum number of splits possible on the given array A?
Here is my (slow) solution, which calls topSplit(A) on the given array:
def topSplitAux(A, C, i, j):
if -1 != C[i][j]:
return C[i][j]
if i == j:
return 0
s = float('-inf')
for k in range(i + 1, j):
if sum(A[i:k]) == sum(A[k:j]):
p1 = 1 + topSplitAux(A, C, i, k)
p2 = 1 + topSplitAux(A, C, k, j)
s = max(s, p1, p2)
C[i][j] = s
if s == float('-inf'): # we couldn't split, game over
C[i][j] = 0
return C[i][j]
def topSplit(A):
# initialize a cache to store solutions already solved
n = len(A)
# the subproblem we are interested in will be in C[0][n]
C = [[-1 for _ in range(n + 1)] for _ in range(n + 1)]
return topSplitAux(A, C, 0, n)
if __name__ == '__main__':
T = int(raw_input())
for t in range(T):
N = int(raw_input())
A = map(int, raw_input().split())
n = len(A)
print topSplit(A)
Here's a simple test case:
3
3
3 3 3
4
2 2 2 2
7
4 1 0 1 1 0 1
with expected result:
0
2
3
Any help on making this solution faster would be greatly appreciated. Thanks!

Python: TypeError: list indices must be integers, not str

I'm going to do Matrix Addition on Python.(Not finish). But it shows an error.
m, n = (int(i) for i in raw_input().split())
a = [[0 for i in range(m)] for j in range(n)]
b = [[0 for i in range(m)] for j in range(n)]
c = []
total = []
for i in range(m):
x = raw_input()
for j in range(n):
value = [int(i) for i in x.split()]
c[i][j] = a[i][j]
#c.append(value)
print a
for i in c:
print i
I want to input
3 3 <-- matrix dimensional m*n
1 2 3 >
3 2 1 > matrix A
1 3 2 >
1 1 1 >
1 1 1 > matrix B
1 1 1 >
and shows as
2 3 4 >
4 3 2 > matrix A + B
2 4 3 >
You are using i in your outer for loop, and it is an int. Then in the loop you have:
value = [int(i) for i in x.split()]
which makes i a string (which is what split returns). Maybe you think there is some sort of scoping inside [ ]? There isn't. You have a name collision, change one of them.
You are using same variable in inner for loop.
for i in range(m):
x = raw_input()
for j in range(n):
# variable i is refering to outer loop
value = [int(p) for p in x.split()]
c[i][j] = a[i][j]
#c.append(value)
print a
for i in c:
print i
Beyond the first two answers you'll have a problem with this statement:
c[i][j] = a[i][j]
When the loop starts i will be 0 and that's so far OK, but c is an empty list and has no iterable at the first position so c[0][0] will return an error.
Get rid of it and uncomment the following line:
#c.append(value)
EDIT:
Your code won't return what you want. You'd better make something like this to create a matrix with the given sides:
for i in range(m):
d = []
for j in range(n):
x = raw_input()
d.append(int(x))
c.append(d)
If you have 3 for both m and n, then you will create matrix with sides 3 x 3 saved in the variable c.
In this way you don't have to split the user input. The user can give a number at a time. And you could even change the following line:
x = raw_input()
to:
x = raw_input("{0}. row, {1}. column: ".format(i+1, j+1))
Try it out!
import time
m, n = (int(i) for i in raw_input().split())
a = []
b = []
total = [[0 for i in range(n)] for j in range(m)]
for i in range(m):
x = raw_input()
for j in range(n):
value = [int(i) for i in x.split()]
a.append(value)
#print a
for i in range(m):
x = raw_input()
for j in range(n):
value = [int(i) for i in x.split()]
b.append(value)
#print b
for i in range(m):
for j in range(n):
total[i][j] = a[i][j] + b[i][j]
for i in total:
print ' '.join(map(str, i))
time.sleep(2)
OK! I just figured it out! Thank you
you can also hit this error if you declare an int and treat it like a dict
>>> a = []
>>> a['foo'] = 'bar'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list indices must be integers, not str

Categories

Resources