在python中从概念循环列表创建两个线性列表

在python中从概念循环列表创建两个线性列表,python,circular-list,Python,Circular List,考虑以下列表: >>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'] >>> list(enumerate(circle)) [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h')] 如果圆被概念化为一个循环列表,即圆[0]连接到圆[7],给定一个开始索引和结束索引,其中开始!=最后,我想构

考虑以下列表:

>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']  
>>> list(enumerate(circle))  
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f'), (6, 'g'), (7, 'h')]  
如果圆被概念化为一个循环列表,即圆[0]连接到圆[7],给定一个开始索引和结束索引,其中开始!=最后,我想构造两个列表,分别表示顺时针和逆时针方向的线性遍历顺序

根据“开始”和“结束”的值,我得出以下结论:

案例1:开始<结束

案例2:开始>结束

有没有一种pythonic/更有效/更简单的方法来构建这两个列表

您可以使用itertools.cycle:


也许?

您可以使用lambda表达式创建顺时针和逆时针方法以及列表切片

>>> clockwise = lambda circle, start, end: circle[start:] + circle[:end+1] if start > end else circle[start:end+1]
>>> counter_clockwise = lambda circle, start, end : clockwise(circle, end, start)[::-1]
这有点类似于您所尝试的,但以一种更为通俗易懂的方式

>>> clockwise(circle,1,6)
['b', 'c', 'd', 'e', 'f', 'g']
>>> counter_clockwise(circle,1,6)
['b', 'a', 'h', 'g']
>>> clockwise(circle,6,1)
['g', 'h', 'a', 'b']
>>> counter_clockwise(circle,6,1)
['g', 'f', 'e', 'd', 'c', 'b']
您可以使用集合模块中的deque来处理逆时针条件的某些部分,如本例所示。如果需要,您可以对其进行修改或改进:

from collections import deque

circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']


clockwise = lambda x,start,end: x[start:end+1] if start < end else x[start:] + x[:end+1]

def counter_clockwise(itertable, start, end):
    if end > start:
        a = deque(itertable[:start+1])
        b = deque(itertable[end:])
        a.rotate()
        b.rotate()
        # Or:
        # return list(a.__iadd__(b))
        return list(a) + list(b)

    if end < start:
        return itertable[start:end-1:-1]


print("start > end:")
start, end = 6,1
print(clockwise(circle, start, end))
print(counter_clockwise(circle, start, end))

print("start < end:")
start, end = 1,6
print(clockwise(circle, start, end))
print(counter_clockwise(circle, start, end))
输出:

start > end:
['g', 'h', 'a', 'b']
['g', 'f', 'e', 'd', 'c', 'b']
start < end:
['b', 'c', 'd', 'e', 'f', 'g']
['b', 'a', 'h', 'g']

我没有确切的答案,但Numpy在其数组实现中有一系列有用的功能。@Xorgon抱歉,不允许使用Numpy。但是当开始>结束时,情况如何?
import itertools

def slice_it(circle,start,end,step=1):
    if end < start and step > 0:
        end = len(circle)+end
    if step < 0:
        return list(itertools.islice(itertools.cycle(circle),end,start,-1*step))[::-1]
    return list(itertools.islice(itertools.cycle(circle),start,end,step))

circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']

print slice_it(circle,6,1)
print slice_it(circle,6,1,-1)
>>> clockwise = lambda circle, start, end: circle[start:] + circle[:end+1] if start > end else circle[start:end+1]
>>> counter_clockwise = lambda circle, start, end : clockwise(circle, end, start)[::-1]
>>> clockwise(circle,1,6)
['b', 'c', 'd', 'e', 'f', 'g']
>>> counter_clockwise(circle,1,6)
['b', 'a', 'h', 'g']
>>> clockwise(circle,6,1)
['g', 'h', 'a', 'b']
>>> counter_clockwise(circle,6,1)
['g', 'f', 'e', 'd', 'c', 'b']
from collections import deque

circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']


clockwise = lambda x,start,end: x[start:end+1] if start < end else x[start:] + x[:end+1]

def counter_clockwise(itertable, start, end):
    if end > start:
        a = deque(itertable[:start+1])
        b = deque(itertable[end:])
        a.rotate()
        b.rotate()
        # Or:
        # return list(a.__iadd__(b))
        return list(a) + list(b)

    if end < start:
        return itertable[start:end-1:-1]


print("start > end:")
start, end = 6,1
print(clockwise(circle, start, end))
print(counter_clockwise(circle, start, end))

print("start < end:")
start, end = 1,6
print(clockwise(circle, start, end))
print(counter_clockwise(circle, start, end))
start > end:
['g', 'h', 'a', 'b']
['g', 'f', 'e', 'd', 'c', 'b']
start < end:
['b', 'c', 'd', 'e', 'f', 'g']
['b', 'a', 'h', 'g']