python - 在 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 中创建一个平滑的旋转系统,但我试图计算角度不起作用,我问这个问题是为了解决我试图实现的另一个想法的问题。我最终接受了帮助我建立平滑轮换系统的答案,但是下面有原始问题的相关答案。
解决方案
带角度的算术
您的目标不是切片、连接或反转列表。您的目标是使用度数进行基本算术运算,并将结果保持在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_angle
ifincrement
不是整数。
推荐阅读
- javascript - 将 Async/Await 与 Promise.all 与 for 循环一起使用
- vb.net - 连接到 Oracle 10g
- swift - SwiftUI - 如何在点击时更改按钮的图像?
- r - R闪亮将文件输入限制为文件名模式而不仅仅是文件类型
- c - 在 gcc/ld 中创建一个默认为外部定义符号别名的函数
- python - Google Colab 代码更改总是产生“TabError:缩进中制表符和空格的使用不一致”
- javascript - 如何组织我的 Javascript 对象/模块?
- python - 启动我的 Mac 时如何让 Python 程序运行?
- algorithm - 为什么安徒生的指针分析算法是迭代的?
- google-tag-manager - 是否可以在 Google Tag Manager 中将标签限制在某些环境中?