So, I have four lists. Two hold x coordinates (foodX
and newPosXArray
) and the other two hold y coordinates (foodX
and newPosYArray
). Both the food and the newPos arrays are of different dimensions because I have multiple "food sources", and multiple objects searching for the food.
I want to write an if statement that does something when the objects get to within a certain distance of the food.
My attempt with any()
if any(np.sqrt((newPosXArray[u]-foodX[t])**2 + (newPosYArray[u]-foodY[t])**2) <= 0.2 for t in zip(food[0], food[1]) for u in zip(newPosXArray, newPosYArray)):
#dosomething
I am getting an error TypeError: list indices must be integers, not tuple
Edit: maybe I am misunderstanding zip(). I was assuming that it condenses this
if any(np.sqrt((newPosXArray[u]-foodX[t])**2 + (newPosYArray[u]-foodY[t])**2) <= 0.2 for t in foodX for t in foodY for u in newPosXArray for u in newPosYArray):
Typical Values of what I am working with
foodX = [5,5,-5,-5]
foodY = [5,-5,5,-5]
In [65]: newPosXArray
Out[65]:
[-0.012880860643600167,
-0.566815786730638,
0.7905336304903405,
0.09006991095474826,
0.26518652615441063,
0.3161232055076695,
0.681255361368023,
-0.6849985596071202,
0.7140832628874829,
0.4958515031060564]
In [66]: newPosYArray
Out[66]:
[-0.41112817779983235,
-0.08554837651693648,
0.8743935617169996,
-0.9384733737088207,
0.02423386678116546,
-0.3735855691077572,
-0.5251118585489394,
0.3950871276165102,
0.9892320167752822,
-0.7342372054958279]
of course, none of these values will return true in the if statement because none are within a 0.2 radius of any of the food coordinates
Just to be clear nested loops and zip do not do the same thing:
>>> [(i, j) for i in range(3) for j in range(3)]
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
Whereas:
>>> list(zip(range(3), range(3)))
[(0, 0), (1, 1), (2, 2)]
itertools.product
does the same as next for loops:
>>> import itertools
>>> list(itertools.product(range(3), range(3)))
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
You don't index into the array when you iterate over an array, e.g:
>>> food = [1,2,3,4]
>>> [f+1 for f in food] # Note you did [food[f] for f in food]
[2,3,4,5]
So fixing your second example looks like:
if any(np.sqrt((u_x-t_x)**2 + (u_y-t_y)**2) <= 0.2
for t_x in foodX for t_y in foodY for u_x in newPosXArray for u_y in newPosYArray):
But this iterates foodY for every foodX so assume you do want these to be zipped which would be written:
if any(np.sqrt((u_x-t_x)**2 + (u_y-t_y)**2) <= 0.2
for t_x, t_y in zip(foodX, foodY) for u_x, u_y in zip(newPosXArray, newPosYArray)):
Or using itertools.product
(which personally I don't find any easier to follow in this instance:
import itertools
if any(np.sqrt((u_x-t_x)**2 + (u_y-t_y)**2) <= 0.2
for (t_x, t_y), (u_x, u_y) in itertools.product(zip(foodX, foodY), zip(newPosXArray, newPosYArray))):