any() 中的多个 for 语句 python

multiple for statements in any() python

所以,我有四个列表。两个保持 x 坐标(foodXnewPosXArray),另外两个保持 y 坐标(foodXnewPosYArray)。食物和 newPos 数组都具有不同的维度,因为我有多个 "food sources",并且有多个对象在搜索食物。 我想写一个 if 语句,当对象到达食物的一定距离内时执行某些操作。 我对 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

我收到错误类型错误:列表索引必须是整数,而不是元组

编辑: 也许我误解了 zip()。我假设它浓缩了这个

 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):

我正在使用的典型值

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]

当然,这些值中的 none 在 if 语句中将 return 为真,因为 none 在任何食物坐标

的 0.2 半径范围内

您尝试获取食物[][z],但 z 是元组(来自 zip 方法),也许您打算这样做

food[0][z[0]] 

问题是 u 和 t 是元组,因为 zip 以元组格式将 x 和 y 并排放置。您需要在您打算将列表值用作坐标的地方说 food[0][t[1]]food[1][t[0]]

根据它的观察,您正试图给它一个 x,(x,y) 坐标而不是 x,y 坐标。

这也适用于您将 u 用作列表索引的地方。

if any(np.sqrt((u[0] - t[0]) ** 2 + (u[1] - t[1]) ** 2) <= 0.2 for t in zip(foodX,foodY) for u in zip(newPosXArray,newPosYArray))

从给定的值计算为 False 直到 0.2 值变为 5,考虑到您的初始值有多低,这听起来很奇怪,但这就是距离公式的工作原理。

或者为了便于阅读,您可以将 u 更改为 new,将 t 更改为 current

需要明确的是,嵌套循环和 zip 做的事情不同:

>>> [(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)]

鉴于:

>>> list(zip(range(3), range(3)))
[(0, 0), (1, 1), (2, 2)]

itertools.product 与下一个循环相同:

>>> 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)]

当你遍历一个数组时,你没有索引到数组中,例如:

>>> food = [1,2,3,4]
>>> [f+1 for f in food]     # Note you did [food[f] for f in food]
[2,3,4,5]

所以修复你的第二个例子看起来像:

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):

但是这会为每个 foodX 迭代 foodY,所以假设您确实希望将这些压缩为:

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)):

或使用 itertools.product(我个人认为在这种情况下更容易理解:

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))):

当然,Pythonic 的方法是只使用复数而不是那些沿错误轴分离的二维数据。但是如果你真的需要使用那种数据格式,我猜

any(math.hypot(X-x,Y-y)<.2 for X,Y in zip(foodX,foodY) for x,y in zip(posX,posY))

会做你想做的。