首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中,根据索引及其后面的项对列表进行切片

在Python中,根据索引及其后面的项对列表进行切片
EN

Stack Overflow用户
提问于 2019-05-14 17:42:52
回答 16查看 3.8K关注 0票数 39

假设我有一系列的学位值,如下所示:

代码语言:javascript
运行
复制
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个元素,包括绕到末尾的索引?

所以,把前面的值应用到这个列表中,我会得到这样的结果:

代码语言:javascript
运行
复制
[90, 75, 60, 45, 30, 15, 0, 345, 330, 315, 300, 285, 270]

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

代码语言:javascript
运行
复制
index = DEGREES.index(90)
print(DEGREES[index-12:index]) # start 12 values back, stop at index

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

是否有方法对列表进行切片,以便获得我所使用的索引后面的前12个值?

编辑:

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

EN

回答 16

Stack Overflow用户

回答已采纳

发布于 2019-05-14 18:43:02

带角度的算术

您的目标不是分割、连接或反向列表。您的目标是使用学位完成基本算术,并将结果保持在0359之间。为此,您确实应该使用模数运算符%

代码语言:javascript
运行
复制
>>> 90 % 360
90
>>> 390 % 360
30
>>> -60 % 360
300
>>> 360 % 360
0

回到问题上

如果您只想用常量增量对度使用这种切片,则可以直接生成所需的列表:

代码语言:javascript
运行
复制
>>> 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]

你真正的问题

你在评论中写道:

这一系列的度被设计成与一个平滑的旋转系统一起工作,这是我试图在游戏中创建的。通常,我只会找出当前方向和目标方向之间的区别,然后再从那里开始递增,但是由于旋转是在零度上滚动的,所以我必须对值进行硬编码,以确保它总是走最短的路线。

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

代码语言:javascript
运行
复制
def shortest_rotation(start_angle, end_angle):
    return (end_angle - start_angle + 180) % 360 - 180

下面是一个例子:

代码语言:javascript
运行
复制
>>> 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

现在,您可以创建一个角度列表,以最短的方向旋转:

代码语言:javascript
运行
复制
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)]

例如:

代码语言:javascript
运行
复制
>>> 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]

如果end_angle不是整数,则列表使用浮点数以避免丢失increment

票数 40
EN

Stack Overflow用户

发布于 2019-05-14 17:51:45

或者你可以用deque

代码语言:javascript
运行
复制
from collections import deque
from itertools import islice

dq = deque(reversed((0, 15, 30, 45, 60,
    75, 90, 105, 120,
    135, 150, 165, 180,
    195, 210, 225, 240,
    255, 270, 285, 300,
    315, 330, 345)))

index = dq.index(90)
dq.rotate(-index)
res = list(islice(dq, 13))
# [90, 75, 60, 45, 30, 15, 0, 345, 330, 315, 300, 285, 270]

您可以使用它作为一个函数:

代码语言:javascript
运行
复制
def f(i):
    dq.rotate(-dq.index(i))
    return list(islice(dq, 13))

#  f(90) = [90, 75, 60, 45, 30, 15, 0, 345, 330, 315, 300, 285, 270]
票数 18
EN

Stack Overflow用户

发布于 2019-05-14 17:53:17

像这样的事情可能更直接:

代码语言:javascript
运行
复制
index = DEGREES.index(90)
print([DEGREES[i] for i in range(index, index-13, -1)])
票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56135864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档