List of values to ndimension list - python

could someone give me some ideas of what I can do with this code?
The user will give a number of values as an argument, and the shape will be the dimensions of the list.
The problem here I is with the v variable, I want to use the v variable to index the values(list) so I can change the nth dimension of the list, so for example.
In the example under where i do v+m, I want the index to not start for 0 where i get the value 1 from the value list, but to get the value 5, but I cant find a solution to do this since i need to define v at the start with 0 and check if its not 0.
Any help is appreciated. ps. I dont want to use any numpy arrays or anything other than lists
def test(shape , *values):
n = shape[1]
m = shape[0]
nDim = [[0 for column in range(m)] for row in range(n)]
values = list(values)
for x in range (n):
print(x)
v = 0
if(v%m == 0):
v +=m
for y in range (m):
nDim[x][y] = values[v]
v += 1
return nDim
m = test((4,2) , 1, 2 ,3, 4 , 5 ,6 , 7 , 8)

You are quite close!
It's true you need to set v=0 but you should do that only once, before the first loop, so you won't reset it between loops. And then your modulo condition is not needed at all, as you increment v in every iteration so choose every *values element once.
v = 0
for x in range(n):
for y in range(m):
nDim[x][y] = values[v]
v += 1
You could even omit v as it can be calculated from xand y
nDim[x][y] = values[x * m + y]

I would do it like this:
def to_list_of_lists(shape, *values):
values = list(values)
result = []
for row in range(shape[1]):
start_index = row * shape[0]
stop_index = start_index + shape[0]
result.append(values[start_index:stop_index])
return result
x = to_list_of_lists((4,2) , 1, 2 ,3, 4 , 5 ,6 , 7 , 8)

Related

ValueError The truth value of an array with more than one element is ambiguous Use a any or a all

So I'm trying to create an array of the same size as [A]. What I want is a for-loop that checks if the 1st value of the ith element in the Array == 0, However it keeps telling me that there is more than one element in the truth value of an array when there shouldn't be as I indexed the 1st value of the ith element in my array. Here is my code:
n = 4
N = [i for i in range(1,n+1)]
V = [0] + N
K = N + [5]
M = [0,1]
A = np.array([(i,j,k) for i in V for j in K for k in M if i!=j])
C=[]
for i in A:
if A[i][0]==0:
C.append([0.7])
elif abs(A[i][0]-A[i][1])<=1:
C.append([1])
else:
C.append([0])
When you go through your for loop, i is already each list in A, you can check this with the below:
for i in A:
print(i)
Which returns:
[0 1 0]
[0 1 1]
[0 2 0]
[0 2 1]...
So then calling A[i][0] gives an array each time rather than an integer, so the comparison A[i][0] == 0 is not possible. To fix your problem, either do the below, which will change your i to get an index for every element in A:
for i in range(len(A)):
if A[i][0]==0:
C.append([0.7])
elif abs(A[i][0]-A[i][1])<=1:
C.append([1])
else:
C.append([0])
Or change all instances of A[i][x] to i[x], and use the each list element of A that way, as follows:
for i in A:
if i[0]==0:
C.append([0.7])
elif abs(i[0]-i[1])<=1:
C.append([1])
else:
C.append([0])

What happens when we a negative value in python's for loop?

x = 10
l = [1]
for i in range(x):
# Modified v
print("Row", i + 1, l)
newlist = []
newlist.append(l[0])
for i in range(len(l) - 1):
newlist.append(l[i] + l[i+1])
newlist.append(l[-1])
l = newlist
I dont understand what happens when the index goes negative
When you give negative index, value at that index is returned. For list
a=[1,2,3]
we can say
value 1 is at index 0
value 2 is at index 1
value 3 is at index 2
or
value 3 is at index -1
value 2 is at index -2
value 1 is at index -3
If you go outside this range of indexes which is in this case negative 3 to positive three, you will get
IndexError: list index out of range
For your code, second for block is never executed and hence you are not seeing index error.
x = 10
l = [1]
for i in range(x):
print("Row", i + 1, l)
newlist = []
newlist.append(l[0])
# Length l is 0,so below code inside for is never executed as range is empty
for i in range(len(l) - 1):
newlist.append(l[i] + l[i+1])
newlist.append(l[-1])
l = newlist

Python 3.x Finding saddle points in a matrix

This is my matrix:
1 1 2 5 6 1
5 6 8 5 6 7
10 12 10 12 11 11
8 10 5 6 8 9
6 5 10 12 15 19
and I would like to find it's saddle points.
COORDINATES of Saddle points should be:
2 0
2 2
0 4
So my question is. Can someone show me, how to make this in Python? :)
Here is a Python approach that assembles lists of the indices of all row/column mins and maxs and then uses set operations to find their intersections:
def allSaddles(matrix):
rowmins = []
rowmaxs = []
colmins = []
colmaxs = []
for i,row in enumerate(matrix):
m = min(row)
M = max(row)
for j,x in enumerate(row):
if x == m: rowmins.append((i,j))
if x == M: rowmaxs.append((i,j))
t = [list(column) for column in zip(*matrix)] #transpose of matrix
for j,col in enumerate(t):
m = min(col)
M = max(col)
for i,x in enumerate(col):
if x == m: colmins.append((i,j))
if x == M: colmaxs.append((i,j))
return (set(rowmins) & set(colmaxs)) | (set(rowmaxs) & set(colmins))
M = [[1,1,2,5,6,1],
[5,6,8,5,6,7],
[10,12,10,12,11,11],
[8,10,5,6,8,9],
[6,5,10,12,15,19]]
print(allSaddles(M))
Output: {(0, 4), (2, 0), (2, 2)}
Here is a different way to make it. Note that the input matrix is a np.ndarray :
def saddles(mat : np.ndarray) -> list:
"""
returns the list of all saddle points of the input matrix
"""
(N, M) = mat.shape
jMax = np.argmax(mat, axis = 1) # index of col for max in each row
iMin = np.argmin(mat, axis = 0) # index of row for min in each col
IJMax = [(i,jMax[i]) for i in range(N)] # list of indexes of max of each row
IJMin = [(iMin[j],j) for j in range(M)] # list of indexes of min of each col
maxRowMinCol = list(set(IJMax) & set(IJMin)) # max of row, min of col
iMax = np.argmax(mat, axis = 0) # index of row for max in each col
jMin = np.argmin(mat, axis = 1) # index of col for min in each row
IJMax = [(iMax[j],j) for j in range(M)] # list of indexes of max of each col
IJMin = [(i,jMin[i]) for i in range(N)] # list of indexes of min of each row
minRowMaxCol = list(set(IJMax) & set(IJMin)) # min of row, max of col
return maxRowMinCol + minRowMaxCol
here is my saddle point finder in python
import numpy as np
def is_saddle(row, column, *args):
index = 0
size = row * column
matrix = np.arange(size).reshape(row, column)
for i in range(row):
for j in range(column):
matrix[i][j] = args[0][index]
index = index + 1
print(matrix)
for item_row in matrix:
column_number = 0
min_item = np.amin(item_row)
for i in range(len(item_row)):
if min_item == item_row[i]:
row_number = i
reversed_matrix = matrix.transpose()
max_item = np.amax(reversed_matrix[row_number])
if max_item == min_item:
print("saddle point found : {}".format(min_item))
return matrix
row = input("enter row")
column = input("enter column")
matrix = input("enter the matrix items")
is_saddle(row, column, matrix)
input sample: row = 2, column = 3, matrix = (1,2,3,4,5,6)
I have a different approach, looking for saddle points which are local, based on a few auxiliary 2d arrays:
def find_saddle(arr2d):
xdiff = np.diff(arr2d, axis=0) # Derivative along 1st dim
ydiff = np.diff(arr2d, axis=1) # Derivative along 2nd dim
# Saddle points are not in the "boundary" elements
xdiff1 = xdiff[1: , 1:-1] # Shift matrix skipping 1st row
xdiff2 = xdiff[ :-1, 1:-1] # Cut the last row
ydiff1 = ydiff[1:-1, 1: ] # Same, for columns
ydiff2 = ydiff[1:-1, :-1]
# A saddle points is a local maximum/minimum in one dimension (xdiff1*xdiff2 < 0) and in the other dimension (ydiff1*ydiff2 < 0),
# but only in the combination max1&min2 or min1&max2 (xdiff1*ydiff1 < 0)
ind = np.where((xdiff1*xdiff2 < 0) & (ydiff1*ydiff2 < 0) &
(xdiff1*ydiff1 < 0))
saddle_points = []
if len(ind) > 0:
for j, x in enumerate(ind[0]):
saddle_points.append([x + 1, ind[1][j] + 1])
return saddle_points

Competition practise task (Python)

Not sure if it's the best title. The explanation of what the program is suposed to do is below, my version only works with the first example but it doesn't work in the second when you get for example 1 1 3 1 1 2 because i can't figure out a good way to handle so much variations especially if K is bigger than 3 and the limit is 50. My version:
N, K, M = map(int, input().split())
niz = list(map(int, input().split()))
nizk = list(range(1, K+1))
izlazi = []
for r in range(0, M):
operacija = list(map(int, input().split()))
index = 0
if operacija[0] == 2:
nizkk = []
for z in range(0, len(nizk)):
if nizk[z] in niz:
continue
else:
izlazi.append(-1)
break
for p in range(0, N):
if niz[p] not in nizkk:
nizkk.append(niz[p])
nizkk.sort()
if nizkk == nizk:
index = p
izlazi.append(index+1)
break
else:
continue
else:
index, repl = map(int, operacija[1:])
niz[index - 1] = repl
print(izlazi)
In the first line of the input there should be N, K, M (1 <= N, M <= 100k, 1 <= K <= 50, you don't need to actually check this the numbers that are tested will always be in those ranges). In the second line of input you put a list of numbers which are the lenght of N you entered earlier. M is the number of operations you will do in the following lines of input. There can be 2 operations. If you enter 1 p v(p = index of number you want to replace, v the number you replace it with) or if you enter 2 it needs to find the shortest array of numbers defined by range(1, K+1) in the list of numbers you entered in line 2 and possibly changed with operation 1. If it doesn't exist it should output -1 if it does it should output lenght of numbers in the array you look in(numbers can be like 2, 1, 3 if you're looking for 1, 2, 3, also if you're looking for 1, 2, 3 etc and you have 2, 1, 1, 3 as the shortest one that is the solution and it's lenght is 4). Also the replacement operation doesnt count from 0 but from 1. So watch out when managing lists.
These are the examples you can input in the program ulaz = input, izlaz = ouput:
I have the following idea:
Min length sequence either starts from first element or does not contain first element and hence equals to min length of the same sequence without first element.
So we have recursion here.
For sequence [1,1,3,2,1,1] and [1,2,3] we will have:
Min length from start element [1,1,3,2,1,1] is 4
Min length from start element __[1,3,2,1,1] is 3
Min length from start element ____[3,2,1,1] is 3
Min length from start element ______[2,1,1] is -1
Can stop here.
Result is minimum for [4,3,3] = 3
You have already implemented the part for min length, if it starts from the first element. Need now extract it as a function and create a recursive function.
Some metacode:
function GetMinLength(seq)
{
minLengthFromFirstElement = GetMinLenthFromFirstElement(seq)
minLengthFromRest = GetMinLength(seq[1:]) //recusive call
return Min(minLengthFromFirstElement, minLengthFromRest )//-1 results should not count, add extra code to handle it
}
Unfortunately I don't know python, but I can provide code on F# in case you need it.
EDIT:
Try this:
N, K, M = map(int, input().split())
niz = list(map(int, input().split()))
nizk = list(range(1, K+1))
izlazi = []
def GetMinLengthStartingFromFirstElement(seq):
nizkk = []
for z in range(0, len(seq)):
if seq[z] in nizk:
continue
else:
return -1
for p in range(0, len(seq)):
if seq[p] not in nizkk:
nizkk.append(seq[p])
nizkk.sort()
if nizkk == nizk:
index = p
return index+1
else:
continue
return -1
def GetMinLength(seq):
if len(seq) == 0:
return -1
else:
curMinLength = GetMinLengthStartingFromFirstElement(seq)
if curMinLength == -1:
return -1
minLengthFromRest = GetMinLength(seq[1:])
if minLengthFromRest > -1:
return min(curMinLength,minLengthFromRest)
else:
return curMinLength;
for r in range(0, M):
operacija = list(map(int, input().split()))
index = 0
if operacija[0] == 2:
minLength = GetMinLength(niz)
izlazi.append(minLength)
else:
index, repl = map(int, operacija[1:])
niz[index - 1] = repl
print(izlazi)

Quiver vector from high value toward low value

What I would like to plot is to make vector from high values to low values.
If code would start from:
a = [[1, 8, 9, 10],[2, 15, 3, -1],[3,1,6,11],[13,15,5,-2]]
X,Y = np.meshgrid(np.arange(4), np.arange(4))
U = ?
V = ?
From this point, I should set U and V components of the vector.
The magnitude of each point would be a[x][y]. I don't have much idea of how I can set U and V to make arrow from high to low value at each grid point.
Here's a solution (doesn't require numpy):
import itertools as it
a = [[1, 8, 9, 10],[2, 15, 3, -1],[3,1,6,11],[13,15,5,-2]]
rowSize = len(a[0])
maxVal = a[0][0]
maxIndex = 0
minVal = a[0][0]
minIndex = 0
for k, v in enumerate(it.chain(*a)): # Loop through a flattened list of the values in the array, and locate the indices of the max and min values.
if v > maxVal:
maxVal = v
maxIndex = k
if v < minVal:
minVal = v
minIndex = k
U = (minIndex % rowSize) - (maxIndex % rowSize)
V = (minIndex / rowSize) - (maxIndex / rowSize)
print U, ",", V
OUTPUT
2 , 2
Note that you haven't defined what behavior you want when there are two equal maximum values, as there are in your example. The code above uses the "first" (upper-leftmost) one as the true maximum, and ignores all others.
Explanation:
I flattened the list (which means I read the values like you would the words on a book - first the first row, then the second row, then the third row). Each value got a single index, like so:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
For example, a value in the second row and the third column would get an index of 6, since it's the 7th value if you read the array like a book.
At the end, when we've found the index of the max or min value, we need to get 2D coordinates from the 1D index. So, we can use the mod operator (%) to get the x-value.
For example, 6 % 4 = 2, so X = 2 (the 3rd column)
To get the Y value, we use the integer division operator (/).
For example, 6 / 4 = 1, so Y = 1 (the second row)
The formulas for U and V are simply taking the X and Y values for the max and min and subtracting them to get the vector coordinates, like so:
U = xMin - xMax
V = yMin - yMax
If you're wondering, "why the heck didn't he just use the meshgrid solution I started with", there are two reasons: One, using a non-standard library like numpy is generally undesirable if there is an easy way to solve the problem without non-standard libraries, and two, if you ever need to deal with large arrays, generating a large meshgrid could become time/memory expensive.
Solution that picks shortest vector:
import itertools as it
a = [[1, 8, 9, 10],[2, 15, 3, -1],[3,1,6,11],[13,15,5,-2]]
rowSize = len(a[0])
values = sorted(enumerate(it.chain(*a)), key=lambda x:x[1]) # Pair each value with its 1D index, then sort the list.
minVal = values[0][1]
maxVal = values[-1][1]
maxIndices = map(lambda x:x[0], filter(lambda x:x[1]==maxVal, values)) # Get a list of all the indices that match the maximum value
minIndices = map(lambda x:x[0], filter(lambda x:x[1]==minVal, values)) # Get a list of all the indices that match the minimum value
def getVector(index1, index2, rowSize): # A function that translates a pair of 1D index values to a "quiver vector"
return ((index1 % rowSize) - (index2 % rowSize), (index1 / rowSize) - (index2 / rowSize))
vectors = [getVector(k2, k1, rowSize) for k1, k2 in it.product(maxIndices, minIndices)] # produce a list of the vectors formed by all possible combinations of the 1D indices for maximum and minimum values
U, V = sorted(vectors, key=lambda x:(x[0]*x[0] + x[1]*x[1])**0.5)[0]
print U, ",", V
OUTPUT
2 , 0

Categories