Нарезать список на основе индекса и элементов за ним в Python - PullRequest
39 голосов
/ 14 мая 2019

Скажем, у меня есть массив значений градусов, например:

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 предыдущих значений за индекс, который я использую?

EDIT:

Это оказалось проблемой XY, мой плохой.Первоначально я пытался создать систему плавного вращения в Pygame, и мои попытки рассчитать углы не работали, я задал этот вопрос, чтобы решить проблему с еще одной идеей, которую я пытался реализовать.В итоге я принял ответ, который помог мне настроить систему плавного вращения, но ниже приведены соответствующие ответы на первоначальный вопрос.

Ответы [ 16 ]

1 голос
/ 14 мая 2019

В вашем примере элементы, которые вы хотите распечатать, это DEGREES[-6:6]. Возможно, вы захотите добавить условные выражения, чтобы позаботиться о начальных индексах, которые в конечном итоге будут повторяться. Как то так:

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

index = DEGREES.index(90)
start_idx = index - 12
if start_idx < 0:
    print(DEGREES[start_idx:] + DEGREES[:index + 1])
else:
    print(DEGREES[start_idx:index + 1])

это должно вернуть следующее:

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

которое является вашим решением, но обратное.

1 голос
/ 14 мая 2019

Я бы посоветовал вам попробовать itertools.cycle () для любого количества предыдущих значений.

Просто переверните список и попробуйте cycle().

import itertools

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]
n=12
degrees.reverse()
ind = degrees.index(90)
degrees = degrees[ind:]+degrees[:ind]
rev_cycle = itertools.cycle(degrees)
for i in range(n+1):
    print(next(rev_cycle))

Это эффективно, так как использует генераторы.

1 голос
/ 14 мая 2019

Я думаю, вам нужно сделать некоторую арифметику.

index = DEGREES.index(90) + 1
offset = 12
start = index - offset
length = len(DEGREES)
print(
    list(reversed(DEGREES[max(0, start):index])) + 
    (list(reversed(DEGREES[length + start - 1 :length])))
     if start < 0
     else [])
)

В качестве альтернативы:

1 голос
/ 14 мая 2019

По спискам:

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

value = 90
index = DEGREES.index(value)



result = DEGREES[:index+1][::-1] + DEGREES[index+1:][::-1]
result = result[:13]
print(result)

выход

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

или

RES= [ DEGREES[i] for i in range(index,index-12-1,-1)]
1 голос
/ 14 мая 2019

Причина, по которой вы получили пустой список, в том, что у вас просто нет 12 пунктов до значения 90.

Что вам нужно, это оператор для обработки этого исключения:

index = DEGREES.index(90)
if index >= 12:
    print(DEGREES[index-12:index])
else: 
    print(DEGREES[:index])
1 голос
/ 14 мая 2019

Я думаю, itertools.chain может быть полезно здесь:

from itertools import chain

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
]

def get_list_of_degrees(degree, resulting_list_length):
    index = DEGREES.index(degree)
    lower_index = index - (resulting_list_length)
    if index >= resulting_list_length:
        result = DEGREES[lower_index: index]  # start 12 values back, stop at index
    else:
        result = list(chain(DEGREES[lower_index:], DEGREES[:index])) # start 12 values back, stop at index
    return result

my_degrees = get_list_of_degrees(90, 12)
print(my_degrees)

Выход:

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

Это то, что вы указали, только назад

Возможно, более простым и масштабируемым / изменяемым методом было бы создание углов на лету безDEGREES список.Что-то вроде:

def get_angles(start_angle=90, increment=-15, return_array_size=12):
    angles = [i for i in range(start_angle + increment, start_angle + (return_array_size*increment) + increment, increment)]
    for index in range(len(angles)):
        while angles[index] < 0:
            angles[index] += 360
    return angles

print(get_angles())

Возвращает:

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

Предоставляя вам гибкость, позволяющую легко возвращать только 5 углов или идти с шагом 2 градуса и т. Д. Например,

print(get_angles(increment=-2))

Теперь возвращается:

[88, 86, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66]

С минимальными изменениями в вашем коде (в противном случае вы быдля этого необходимо сгенерировать новый массив DEGREES)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...