Python List in List trouble - python

Before start to tell my problem sorry for my grammar and English is not very good. I'm a Python learner. Today i was working on a project but I have a trouble. I'm trying to make a loop.
coordinates = [[1,2],[2,3],[3,5],[5,6],[7,7`],[1,2]]
Here is my list, I'm trying to create a loop. That loop will substract every first values from each others and every seconds to seconds then print. Let me explain my trouble more simple. [[x,y][x1,y1][x2,y2] I need to substract x1-x then print the result after this x2-x1 then print the result but same time y1-y print then print so console output should looks like this;
1,1
1,2
2,1...
Method i've tried
while True:
for x,y in coordinates:
x = x - y
print(x)
This is not worked because it substracts x values to y values. I know it's too wrong.
I've research on internet but i did not understand this subject very well.
I'm looking for help. Thanks everyone.

A simple and naive implementation
def pr(arr):
i = 1
while i < len(arr):
(x,y) = arr[i]
(a,b) = arr[i-1]
print(x-a, y-b)
i += 1
if __name__ == '__main__':
coordinates = [[1,2],[2,3],[3,5],[5,6],[7,7],[1,2]]
pr(coordinates)
O/P:
1 1
1 2
2 1
2 1
-6 -5

This is fairly similar to your original code:
coordinates = [[1,2],[2,3],[3,5],[5,6],[7,7`],[1,2]]
x_prev = None
for x, y in coordinates:
if x_prev is not None:
print('{}, {}'.format(x - x_prev, y - y_prev)
x_prev, y_prev = x, y
If you want to generalize a bit, for different lengths of coordinates, you could do this:
coordinates = [[1,2],[2,3],[3,5],[5,6],[7,7`],[1,2]]
prev = None
for c in coordinates:
if prev is not None:
print(', '.join(c2-c1 for c1, c2 in zip(prev, c)))
prev = c

You need to iterate over the list using range function so that you can get current and next ones together. So you can do the subtraction in the loop.
coordinates = [[1,2],[2,3],[3,5],[5,6],[7,7],[1,2]]
for i in range(len(coordinates) - 1):
print(coordinates[i+1][0] - coordinates[i][0], coordinates[i+1][1] - coordinates[i][1])

Related

Coding autocorrelation function correctly in python

I have a two data sets, each of which are 325 elements long. One is data along and X-axis, one is data along the y-axis. Together, Q[0] and Q[1] make up Q.
The equation should be something like:
(Q(i+deltai,j) - mean(Q_i,j)) x (Q_i,j - mean(Q_i,j)) / (Q_i,j - mean(Q_i,j))^2
Which is an autocorrelation function. I want to iterate through i + delta i for the first function while looping through the data in Q. I did start to write two for loops for this, and then tried np.correlate. In the end, I think I got confused being new to python and felt like I spent the last few days chasing my tail.
The code I tried is:
I = npzfile['i']
Q = npzfile['q']
U = npzfile['u']
nxside = Q.shape[0]
nyside = Q.shape[1]
for i in numpy.arange(0,nxside-1,1):
result = numpy.correlate(Q[0], Q, mode='full')
result2 = (result/float(result.max()))
plt.plot(result2, '-')
for i in numpy.arange(0,nxside-1,1):
for j in numpy.arange(0, nyside-1,1):
# # # J= (i)
# # # # L = ()
# # # # print L
M = (Q - numpy.mean(Q))
B = (Q[i] - numpy.mean(Q))
K = (Q - numpy.mean(Q))**2
Z = numpy.abs(M*B)/numpy.abs(K)
# print numpy.abs((M*B)/K)
plt.plot(Z, 'ro')
I'd expect the output to be something that varies between 0 and 1 on the y-axis, over 325 elements.

how to sum adjacent tuples/list

I apologise for the terrible description and if this is a duplicated, i have no idea how to phrase this question. Let me explain what i am trying to do. I have a list consisting of 0s and 1s that is 3600 elements long (1 hour time series data). i used itertools.groupby() to get a list of consecutive keys. I need (0,1) to be counted as (1,1), and be summed with the flanking tuples.
so
[(1,8),(0,9),(1,5),(0,1),(1,3),(0,3)]
becomes
[(1,8),(0,9),(1,5),(1,1),(1,3),(0,3)]
which should become
[(1,8),(0,9),(1,9),(0,3)]
right now, what i have is
def counter(file):
list1 = list(dict[file]) #make a list of the data currently working on
graph = dict.fromkeys(list(range(0,3601))) #make a graphing dict, x = key, y = value
for i in list(range(0,3601)):
graph[i] = 0 # set all the values/ y from none to 0
for i in list1:
graph[i] +=1 #populate the values in graphing dict
x,y = zip(*graph.items()) # unpack graphing dict into list, x = 0 to 3600 and y = time where it bite
z = [(x[0], len(list(x[1]))) for x in itertools.groupby(y)] #make a new list z where consecutive y is in format (value, count)
z[:] = [list(i) for i in z]
for i in z[:]:
if i == [0,1]:
i[0]=1
return(z)
dict is a dictionary where the keys are filenames and the values are a list of numbers to be used in the function counter(). and this gives me something like this but much longer
[[1,8],[0,9],[1,5], [1,1], [1,3],[0,3]]
edits:
solved it with the help of a friend,
while (0,1) in z:
idx=z.index((0,1))
if idx == len(z)-1:
break
z[idx] = (1,1+z[idx-1][1] + z[idx+1][1])
del z[idx+1]
del z[idx-1]
Not sure what exactly is that you need. But this is my best attempt of understanding it.
def do_stuff(original_input):
new_original = []
new_original.append(original_input[0])
for el in original_input[1:]:
if el == (0, 1):
el = (1, 1)
if el[0] != new_original[-1][0]:
new_original.append(el)
else:
(a, b) = new_original[-1]
new_original[-1] = (a, b + el[1])
return new_original
# check
print (do_stuff([(1,8),(0,9),(1,5),(0,1),(1,3),(0,3)]))

backtracking not trying all possibilities

so I've got a list of questions as a dictionary, e.g
{"Question1": 3, "Question2": 5 ... }
That means the "Question1" has 3 points, the second one has 5, etc.
I'm trying to create all subset of question that have between a certain number of questions and points.
I've tried something like
questions = {"Q1":1, "Q2":2, "Q3": 1, "Q4" : 3, "Q5" : 1, "Q6" : 2}
u = 3 #
v = 5 # between u and v questions
x = 5 #
y = 10 #between x and y points
solution = []
n = 0
def main(n_):
global n
n = n_
global solution
solution = []
finalSolution = []
for x in questions.keys():
solution.append("_")
finalSolution.extend(Backtracking(0))
return finalSolution
def Backtracking(k):
finalSolution = []
for c in questions.keys():
solution[k] = c
print ("candidate: ", solution)
if not reject(k):
print ("not rejected: ", solution)
if accept(k):
finalSolution.append(list(solution))
else:
finalSolution.extend(Backtracking(k+1))
return finalSolution
def reject(k):
if solution[k] in solution: #if the question already exists
return True
if k > v: #too many questions
return True
points = 0
for x in solution:
if x in questions.keys():
points = points + questions[x]
if points > y: #too many points
return True
return False
def accept(k):
points = 0
for x in solution:
if x in questions.keys():
points = points + questions[x]
if points in range (x, y+1) and k in range (u, v+1):
return True
return False
print(main(len(questions.keys())))
but it's not trying all possibilities, only putting all the questions on the first index..
I have no idea what I'm doing wrong.
There are three problems with your code.
The first issue is that the first check in your reject function is always True. You can fix that in a variety of ways (you commented that you're now using solution.count(solution[k]) != 1).
The second issue is that your accept function uses the variable name x for what it intends to be two different things (a question from solution in the for loop and the global x that is the minimum number of points). That doesn't work, and you'll get a TypeError when trying to pass it to range. A simple fix is to rename the loop variable (I suggest q since it's a key into questions). Checking if a value is in a range is also a bit awkward. It's usually much nicer to use chained comparisons: if x <= points <= y and u <= k <= v
The third issue is that you're not backtracking at all. The backtracking step needs to reset the global solution list to the same state it had before Backtracking was called. You can do this at the end of the function, just before you return, using solution[k] = "_" (you commented that you've added this line, but I think you put it in the wrong place).
Anyway, here's a fixed version of your functions:
def Backtracking(k):
finalSolution = []
for c in questions.keys():
solution[k] = c
print ("candidate: ", solution)
if not reject(k):
print ("not rejected: ", solution)
if accept(k):
finalSolution.append(list(solution))
else:
finalSolution.extend(Backtracking(k+1))
solution[k] = "_" # backtracking step here!
return finalSolution
def reject(k):
if solution.count(solution[k]) != 1: # fix this condition
return True
if k > v:
return True
points = 0
for q in solution:
if q in questions:
points = points + questions[q]
if points > y: #too many points
return True
return False
def accept(k):
points = 0
for q in solution: # change this loop variable (also done above, for symmetry)
if q in questions:
points = points + questions[q]
if x <= points <= y and u <= k <= v: # chained comparisons are much nicer than range
return True
return False
There are still things that could probably be improved in there. I think having solution be a fixed-size global list with dummy values is especially unpythonic (a dynamically growing list that you pass as an argument would be much more natural). I'd also suggest using sum to add up the points rather than using an explicit loop of your own.

Issues with using np.linalg.solve in Python

Below, I'm trying to code a Crank-Nicholson numerical solution to the Navier-Stokes equation for momentum (simplified with placeholders for time being), but am having issues with solving for umat[timecount,:], and keep getting the error "ValueError: setting an array element with a sequence". I'm extremely new to Python, does anyone know what I could do differently to avoid this problem?
Thanks!!
def step(timesteps,dn,dt,Numvpts,Cd,g,alpha,Sl,gamma,theta_L,umat):
for timecount in range(0, timesteps+1):
if timecount == 0:
umat[timecount,:] = 0
else:
Km = 1 #placeholder for eddy viscosity
thetaM = 278.15 #placeholder for theta_m for time being
A = Km*dt/(2*(dn**2))
B = (-g*dt/theta_L)*thetaM*np.sin(alpha)
C = -dt*(1/(2*Sl) + Cd)
W_arr = np.zeros(Numvpts+1)
D = np.zeros(Numvpts+1)
for x in (0,Numvpts): #creating the vertical veocity term
if x==0:
W_arr[x] = 0
D[x] = 0
else:
W_arr[x] = W_arr[x-1] - (dn/Sl)*umat[timecount-1,x-1]
D = W_arr/(4*dn)
coef_mat_u = Neumann_mat(Numvpts,D-A,(1+2*A),-(A+D))
b_arr_u = np.zeros(Numvpts+1) #the array of known quantities
umat_forward = umat[timecount-1,2:Numvpts]
umat_center = umat[timecount-1,1:Numvpts-1]
umat_backward = umat[timecount-1,0:Numvpts-2]
b_arr_u = np.zeros(Numvpts+1)
for j in (0,Numvpts):
if j==0:
b_arr_u[j] = 0
elif j==Numvpts:
b_arr_u[j] = 0
else:
b_arr_u[j] = (A+D[j])*umat_backward[j]*(1-2*A)*umat_center[j] + (A-D[j])*umat_forward[j] - C*(umat_center[j]*umat_center[j]) - B
umat[timecount,:] = np.linalg.solve(coef_mat_u,b_arr_u)
return(umat)
Please note that,
for i in (0, 20):
print(i),
will give result 0 20 not 0 1 2 3 4 ... 20
So you have to use the range() function
for i in range(0, 20 + 1):
print(i),
to get 0 1 2 3 4 ... 20
I have not gone through your code rigorously, but I think the problem is in your two inner for loops:
for x in (0,Numvpts): #creating the vertical veocity term
which is setting values only at zero th and (Numvpts-1) th index. I think you must use
for x in range(0,Numvpts):
Similar is the case in (range() must be used):
for j in (0,Numvpts):
Also, here j never becomes == Numvpts, but you are checking the condition? I guess it must be == Numvpts-1
And also the else condition is called for every index other than 0? So in your code the right hand side vector has same numbers from index 1 onwards!
I think the fundamental problem is that you are not using range(). Also it is a good idea to solve the NS eqns for a small grid and manually check the A and b matrix to see whether they are being set correctly.

python list of lists index out of range [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I have read in a matrix of numbers and I am trying to work with each cell and perform tests on each one. If the number is != 0 I want to use it so if it is 0 I am currently incrementing x and y to find a non zero number.
In the end I will just be first looking across the top row and then if they are all 0 start looking down the first column and this works fine as long as I am referring to just one (row or column).
Why am I receiving this error? Am I thinking incorrectly about how the cells are set up or is my code wrong?
The matrix looks like this:
0,2,4,1,6,0,0
2,0,0,0,5,0,0
4,0,0,0,0,5,0
1,0,0,0,1,1,0
6,5,0,1,0,5,5
0,0,5,1,5,0,0
0,0,0,0,5,0,0
When I start trying to do this:
y = y + 5
x = x + 5
node = Alist[x][y]
I receieve an error saying:
node = Alist[x][y]
IndexError: list index out of range
If I was to just write:
y = y + 5
node = Alist[x][y]
print node
It would work completely fine but when I introduce both x and y I start to get list index out of range problems. In my mind it should now read:
node = Alist[5][5]
Which is 0 if you follow the matrix
def create_matrix(file):
with open('network.txt') as f:
Alist = []
for line in f:
part = []
for x in line.split(','):
part.append(int(x))
Alist.append(part)
return Alist
#used to set the start node, used once
def start_node(Alist):
x=0
y=0
#point node to pos [0][0] of Alist
node = Alist[x][y]
#test if node == 0
while node == 0:
y = y + 5
x = x + 5
node = Alist[x][y]
#create a list to hold co-ordinates
if node != 0:
#return node for processing by check_neighbours
return node, x, y
#def current_node(Alist, x, y)
#test neighbours to see if they can be used
def check_neighbours(node, Alist, i, j):
#print out values of x and y
print "x = %d" %i
print "y = %d" % j
print "node in check_neighbours is " + str(node)
#running of code begins here
def main():
file = ("F:/media/KINGSTON/Networking/network.txt")
Alist = create_matrix(file)
node, x, y = start_node(Alist)
check_neighbours(node, Alist, x, y)
main()
It's the second iteration round the loop that's failing, because it sets x and y to 10, where you only have 7 items in each dimension.
Your loop while node == 0: moves down the diagonal of the matrix five steps at a time, falling off the end. It would fall off the end even if it went one at a time, because that diagonal is all zeros.
Perhaps you meant if node == 0?
I don't know what the code is actually trying to do, but you need to rethink the algorithm. :-)
If I follow your code in start_node you are
a) Not performing any kind of bounds checking
and
b) Jumping down the diagonal elements of your matrix, which are all zero, until you go out of bounds, as your error tells you. Presumably when you are incrementing only one of your indices you are lucky in that you hit a non-zero element before going out of bounds
In this code, start_node returns the first non-zero "node".
I used mat instead of Alist as I feel it is more Pythonic.
Comments note the changes and tips.
def create_matrix(fname): # don't use built-ins as variable names!!
with open(fname) as f: # you take filename in arguments, but don't use it..
# why not use in-built functions and list comprehensions ?
mat = [map(int,line.split(',')) for line in f]
return mat
#used to set the start node, used once
def start_node(mat):
# for each row in matrix (index)..
for i1 in range(len(mat)):
# for each cell in row (index)..
for i2 in range(len(mat[i1])):
# mat[i1][i2] is the node/cell..
if mat[i1][i2] != 0:
# return node, x, y :)
return mat[i1][i2], i2, i1
# test neighbours to see if they can be used
# same as yours
def check_neighbours(node, Alist, i, j):
#print out values of x and y
print "x = %d" % (i,)
print "y = %d" % (j,)
print "node (in check_neighbours) is " + str(node)
#running of code begins here
def main():
fname = "F:/media/KINGSTON/Networking/network.txt"
mat = create_matrix(fname)
node, x, y = start_node(mat)
check_neighbours(node, mat, x, y)
main()
Explanation:
mat = [map(int,line.split(',')) for line in f]
This is a list comprehension. map is an in-built method.
The for loops in start_node...
for i1 in range(len(mat)): # 1
for i2 in range(len(mat[i1])): # 2
len(mat) is the number of rows in your matrix.
range(len(mat)) gives us the indexes of each row.
len(mat[i1]) gives us the length of the current row.
range(len(mat[i1])) gives us the indexes of each column in that row.
In your code, you were incrementing both x and y (here i2 and i1 respectively) so were moving diagonally.

Categories

Resources