首页 > 解决方案 > 在 Python 中根据索引及其后面的项目对列表进行切片

问题描述

假设我有一个度数数组,如下所示:

DEGREES = [
    0, 15, 30, 45, 60,
    75, 90, 105, 120,
    135, 150, 165, 180,
    195, 210, 225, 240,
    255, 270, 285, 300,
    315, 330, 345,
]

我会选择一个角度,然后能够平分这个假设的圆,以便更容易找到到目标方向的最短路线。

话虽如此,我如何选择一个特定的值,例如90,然后能够找到其后面的前 12 个元素,包括环绕到末尾的索引?

因此,采用较早的值并应用于该列表,我会得到如下信息:

[90, 75, 60, 45, 30, 15, 0, 345, 330, 315, 300, 285, 270]

使用切片表示法,我尝试这样做:

index = DEGREES.index(90)
print(DEGREES[index-12:index]) # start 12 values back, stop at index

但这只会打印一个空数组。

有没有办法对列表进行切片,这样我就可以得到我正在使用的索引后面的 12 个以前的值?

编辑:

事实证明这是一个 XY 问题,我的错。最初,我试图在 Pygame 中创建一个平滑的旋转系统,但我试图计算角度不起作用,我问这个问题是为了解决我试图实现的另一个想法的问题。我最终接受了帮助我建立平滑轮换系统的答案,但是下面有原始问题的相关答案。

标签: pythonlist

解决方案


带角度的算术

您的目标不是切片、连接或反转列表。您的目标是使用度数进行基本算术运算,并将结果保持在0和之间359。为此,您确实应该使用运算符%

>>> 90 % 360
90
>>> 390 % 360
30
>>> -60 % 360
300
>>> 360 % 360
0

回到问题

如果您只想将此切片用于具有恒定增量的度数,则可以直接生成所需的列表:

>>> STEP = 15
>>> list(range(0, 360, STEP))
[0, 15, 30, 45, 60, 75, 90, 105, 120, 135, 150, 165, 180, 195, 210, 225, 240, 255, 270, 285, 300, 315, 330, 345]
>>> def previous_degrees(start, n, step=STEP):
...     return [(start - i * step) % 360 for i in range(n + 1)]
... 
>>> previous_degrees(90, 12)
[90, 75, 60, 45, 30, 15, 0, 345, 330, 315, 300, 285, 270]
>>> previous_degrees(90, 12, 30)
[90, 60, 30, 0, 330, 300, 270, 240, 210, 180, 150, 120, 90]
>>> previous_degrees(90, 6, 45)
[90, 45, 0, 315, 270, 225, 180]

你真正的问题

你在评论中写道:

这个度数数组旨在与我试图在 pygame 中创建的平滑旋转系统一起使用。通常我只会找到当前方向和目标方向之间的差异并从那里增加,但由于旋转在零处翻转,我必须对值进行硬编码以确保它总是走最短的路线。

从两个角度,您需要确定是顺时针还是逆时针转动。您可以再次使用模数来确保旋转在 -180° 和 179° 之间:

def shortest_rotation(start_angle, end_angle):
    return (end_angle - start_angle + 180) % 360 - 180

这是一个例子:

>>> shortest_rotation(0, 90)
90
>>> shortest_rotation(90, 0)
-90
>>> shortest_rotation(90, 90)
0
>>> shortest_rotation(90, 330)
-120
>>> shortest_rotation(0, 180)
-180
>>> shortest_rotation(0, 181)
-179
>>> shortest_rotation(0, 179)
179
>>> shortest_rotation(10, 350)
-20

您现在可以创建角度列表,沿最短方向转动:

def rotation_steps(start_angle, end_angle, n):
    increment = shortest_rotation(start_angle, end_angle) / n
    return [(start_angle + i * increment) % 360 for i in range(n + 1)]

举个例子:

>>> rotation_steps(90, 270, 12)
[90.0, 75.0, 60.0, 45.0, 30.0, 15.0, 0.0, 345.0, 330.0, 315.0, 300.0, 285.0, 270.0]
>>> rotation_steps(10, 350, 2)
[10.0, 0.0, 350.0]

该列表使用 float 以避免丢失end_angleifincrement不是整数。


推荐阅读