【问题标题】:multiple for statements in any() pythonany() python 中的多个 for 语句
【发布时间】:2015-09-13 19:52:43
【问题描述】:

所以,我有四个列表。两个保存 x 坐标(foodXnewPosXArray),另外两个保存 y 坐标(foodXnewPosYArray)。 food 和 newPos 数组都具有不同的维度,因为我有多个“食物来源”和多个搜索食物的对象。 我想写一个 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

我收到一个错误 TypeError: list indices must be integers, not tuple

编辑: 也许我误解了 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]

当然,这些值都不会在 if 语句中返回 true,因为它们都不在任何食物坐标的 0.2 半径范围内

【问题讨论】:

  • 不确定您处理的项目数量,但如果数量很少,则可以通过创建保存坐标的对象,然后创建 calcDistance 方法来提高代码清晰度。 class Point(object): def __init__(self, x, y): self.x=x, self.y=ydef calcDistance(self, otherPoint): return math.sqrt((self.x - otherPoint.x)**2 + (self.y - otherPoint.y)**2)。然后你的循环变成:if any(f.calcDistance(y) for f in food for y in newPos):

标签: python arrays for-loop numpy any


【解决方案1】:

为了清楚嵌套循环和 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 的作用与 next for 循环相同:

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

【讨论】:

  • 感谢您的澄清!听起来我需要试着想一种不同的方式来做我想做的事
【解决方案2】:

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

food[0][z[0]] 

【讨论】:

  • 我编写食物数组的方式有点让人分心。让我编辑一下。
【解决方案3】:

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

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

会做你想做的。

【讨论】:

    【解决方案4】:

    问题在于 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 更改为newt 更改为current

    【讨论】:

    • 嗯。我写食物数组的方式有点让人分心。让我编辑一下。
    • 查看编辑我的意思。 foodX 和 foodY 又是从哪里来的?
    • 增加了价值的例子
    猜你喜欢
    • 2021-07-19
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2018-09-27
    • 2016-04-20
    相关资源
    最近更新 更多