Question:-Write a Python function transpose(m) that takes as input a two dimensional matrix m and returns the transpose of m. The argument m should remain undisturbed by the function.
def transpose(l):
m=l[:]
lst=[[] for x in range(len(m[0)]
for i in range(0,len(m)):
for j in range(0,len(m[i])):
lst[j].append(m[i][j])
return lst
l=[[1,2,3,4,5],[4,5,6,7,8,9]]
ERROR
lst[j].append(m[i][j])
IndexError: list index out of range
Your List l has two lists with 5 and 6 elements.
So, the range of j in range(len(m[1])) is 0 - 5 (6 numbers), which results in index out of range for lst (which only have 5 elements).
def transpose(l):
lst=[[] for x in range(len(l[0]))]
for i in range(len(l)):
for j in range(len(l[i])):
lst[j].append(l[i][j])
return lst
l = [[1,2,3,4,5],[4,5,6,7,8]]
But I would add a checking part at the beginning of the function
def transpose(l):
iterator = iter(l)
lists_len = len(next(iterator))
if not all(len(a) == lists_len for a in iterator):
# Do something here
lst=[[] for x in range(len(l[0]))]
for i in range(len(l)):
for j in range(len(l[i])):
lst[j].append(l[i][j])
return lst
Related
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.
I have to write a function empty_matrix that must return a list of lists (a matrix)
desired output:
empty_matrix(3,4)
returns a list with three lists each of length four:
[[None,None,None,None],[None,None,None,None],[None,None,None,None]]
What should I change in my code below???
def empty_matrix(row,column):
first_col = []
for x in range(len(matrix)):
sublist = matrix[x]
for y in range(len(sublist)):
first_col.append(matrix[x][y])
Using a list comprehension:
def empty_matrix(row, column):
return [[None for _ in range(row)] for _ in range(column)]
But to fix your code, you're using len on variables matrix and sublist that aren't defined, your indentation is off, try something like this if you don't want to use a list comprehension.
def empty_matrix(row, column):
matrix = []
for c in range(column):
column = []
for r in range(row):
column.append(None)
matrix.append(column)
return matrix
I'm trying to create a program, in which the user inputs 2 lists of strings.
say l1 and l2 which are of same size, say 'n'.
now the output must be given as the concatenated list of 1st element of l1 and last element of l2, and so on.
That is i'th element of l1 and (n-1)th element of l2.
It's giving an error "Index out of range" for the 3rd for loop
n=int(input())
l1=[]
for x in range(n):
e1=input()
l1.append(e1)
l2=[]
for x in range(n):
e2=input()
l2.append(e2)
for x in range(n):
k=l1[x]+l2[n-x]
print(k)
result:
>>> Index out of range
Replace this:
for x in range(n):
k=l1[x]+l2[n-x]
with this:
k = [a+b for a,b in zip(l1, reversed(l2))]
Basically you have to avoid indexing at all cost. And poor naming practice: l1 looks very much like I1 or ll. All your code can be simplified to:
n = int(input())
part1 = [input() for i in range(n)]
part2 = [input() for i in range(n)]
k = [a+b for a,b in zip(part1, reversed(part2))]
and so on...
Answering your question:
>>> part1 = ['app', 'ban']
>>> part2 = ['ana', 'le']
>>> print ' '.join( a+b for a,b in zip(part1, reversed(part2)))
apple banana
Looks fine to me.
I think doing n-x-1 can solve the problem as list index start from zero and ended numberOfelement -1:
n=int(input())
l1=[ ]
for x in range(n):
e1=input()
l1.append(e1)
l2=[ ]
for x in range(n):
e2=input()
l2.append(e2)
for x in range(n):
k=l1[x]+l2[n-x-1]
print(k)
That's because x in the first iteration of loop would be 0 and then n-0 will be n which is not the last array index. The last iteration number is n-1.
The problem is just the starting point of the array that is need to be changed.
And also you have to initiate a new list to have the results in there.
So you need to change it like this:
k = []
for x in range(n):
k.append(l1[x]+l2[n-x-1])
Using this the first loop would be n-0-1 which is n-1
And the last loop would be n-(n-1)-1 which is 0. So it ranges from 0 to n-1 and that's perfect.
Also you can have a much simpler version like below:
k = [l1[x]+l2[-x-1] for x in range(n)]
n=int(input())
l1=[]
l2 =[]
for x in range(n):
e1=input()
l1.append(e1)
for x in range(n):
e2=input()
l2.append(e2)
k=''
for i,j in zip(l1,reversed(l2)):
k+=i+j
print(k)
input
5
a
b
c
d
e
e
d
c
b
a
output
aabbccddee
other way to do it,
n = int(input())
l1 = list(map(str,input().split()))
l2 = list(map(str,input().split()))
if len(l2)==n and len(l2)==n:
res=''
for i,j in zip(l1, reversed(l2)):
res+=i+j
print(res)
else:
print('len of string not matched')
input
5
abcde
edcba
output
aabbccddee
solution for OP example given in comment
l1 = ['mot','cy']
l2 = ['cle','or']
#method 1
#sol = ' '.join([i+j for i,j in zip(l1,reversed(l2))])
#method 2
sol =''
for i,j in zip(l1,reversed(l2)):
sol+=i+j+' '
sol.strip()
print(sol)
output
motor cycle
Solution to your problem:
n=int(input())
l1=[]
for x in range(n):
e1=input()
l1.append(e1)
l2=[]
for x in range(n):
e2=input()
l2.append(e2)
k=[l1[x]+l2[n-x-1] for x in range(n)]
print(k)
How would you rewrite the following sliding window code using generator?
My issue is that each iteration I want to consume k=100 elements or the number of elements left.
n=1005
m=5
step=2
a=[(i,j) for i in range(0,n-m+1,step) for j in range(0,n-m+1,step) if i<j]
I came up with this solution:
Maybe this was a dumb question. Anyways here is a possible, non-optimal solution:
def my_gen(n,m,k,step):
res = []
count = 0
for i in range(0,n-m+1,step):
for j in range(0,n-m+1,step):
if i<j:
res.append((i,j))
count += 1
if count%k == 0:
yield res
res = []
yield res
Validating it works:
n=104
m=5 # size of the window
step=2
k=8
a=[(i,j) for i in range(0,n-m+1,step) for j in range(0,n-m+1,step) if i<j]
gen=my_gen(n,m,k,step)
b=[]
for g in gen:
b.extend(g)
for x,y in zip(a,b):
assert(x==y)
I was wondering is there a R equivalent of this list comprehension of a duple in python? What it does is extract certain elements from a nested list i given indices from j:
i = [[1,2,3],[2,3,4],[2,4,2]]
j = [1,2,0]
whatineed = [x[y] for x,y in izip(i,j)]
Presumably, in R the corresponding i and j would be lists/vectors:
i = list(c(1,2,3),c(2,3,4),c(2,4,2))
j = c(2,3,1)
or
j = list(2,3,1)
Thank you so much for your help in advance!!
In R you use Map function:
i = list(c(1,2,3),c(2,3,4),c(2,4,2))
j = c(2,3,1)
Map(`[`, i, j)
[[1]]
[1] 2
[[2]]
[1] 4
[[3]]
[1] 2
You can also use mapply which returns a vector instead of a list:
mapply(`[`, i, j)
[1] 2 4 2