从 python 中的概念循环列表创建两个线性列表
Create two linear lists from a conceptual circular list in python
考虑以下列表:
>>> 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')]
如果 circle
被概念化为循环列表,即 circle[0]
连接到 circle[7]
,给定一个 start
索引和一个 end
索引,其中 start != end
,我想构造两个分别代表顺时针和逆时针方向的线性遍历顺序的列表。
根据 start
和 end
的值,我得出以下结论:
案例 1:start < end
>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> start, end = 1, 6
>>> clockwise = circle[start:end+1]
>>> clockwise
['b', 'c', 'd', 'e', 'f', 'g']
>>> counter_clockwise = circle[start::-1] + circle[:end-1:-1]
>>> counter_clockwise
['b', 'a', 'h', 'g']
案例 2:start > end
>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> start, end = 6, 1
>>> clockwise = circle[start:] + circle[:end+1]
>>> clockwise
['g', 'h', 'a', 'b']
>>> counter_clockwise = circle[start:end-1:-1]
>>> counter_clockwise
['g', 'f', 'e', 'd', 'c', 'b']
是否有 pythonic/more-efficient/easier 构建这两个列表的方法?
您可以使用 itertools.cycle
:
import itertools
circle = ['a', 'b', 'c', 'd', 'e', 'f',
'g', 'h']
def clockwise(start, end):
endless = itertools.cycle(circle)
if start > end:
end = start + (len(circle)-(start
-end))
return [next(endless) for i in range
(end+1)][start:]
def counter_clockwise(start, end):
endless = itertools.cycle(circle)
if end > start:
start = end + (len(circle)-(end
-start))
return [next(endless) for i in range
(start+1)][end:][::-1]
# start < end:
forward=clockwise(1, 6)
b1=counter_clockwise(1, 6)
#start > end:
f1=clockwise(6, 1)
backward=counter_clockwise(6, 1)
print(forward)
print(b1)
print(f1)
print(backward)
输出:
['b', 'c', 'd', 'e', 'f', 'g']
['b', 'a', 'h', 'g']
['g', 'h', 'a', 'b']
['g', 'f', 'e', 'd', 'c', 'b']
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)
也许?
您可以使用 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]
这与您尝试过的有点相似,但是更像 Python 的方式和更通用的方式!
>>> 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']
您可以使用 collections
模块中的 deque
来处理 counter_clockwise
条件的某些部分,例如此示例(您可以根据需要对其进行修改或改进):
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']
考虑以下列表:
>>> 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')]
如果 circle
被概念化为循环列表,即 circle[0]
连接到 circle[7]
,给定一个 start
索引和一个 end
索引,其中 start != end
,我想构造两个分别代表顺时针和逆时针方向的线性遍历顺序的列表。
根据 start
和 end
的值,我得出以下结论:
案例 1:start < end
>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> start, end = 1, 6
>>> clockwise = circle[start:end+1]
>>> clockwise
['b', 'c', 'd', 'e', 'f', 'g']
>>> counter_clockwise = circle[start::-1] + circle[:end-1:-1]
>>> counter_clockwise
['b', 'a', 'h', 'g']
案例 2:start > end
>>> circle = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> start, end = 6, 1
>>> clockwise = circle[start:] + circle[:end+1]
>>> clockwise
['g', 'h', 'a', 'b']
>>> counter_clockwise = circle[start:end-1:-1]
>>> counter_clockwise
['g', 'f', 'e', 'd', 'c', 'b']
是否有 pythonic/more-efficient/easier 构建这两个列表的方法?
您可以使用 itertools.cycle
:
import itertools
circle = ['a', 'b', 'c', 'd', 'e', 'f',
'g', 'h']
def clockwise(start, end):
endless = itertools.cycle(circle)
if start > end:
end = start + (len(circle)-(start
-end))
return [next(endless) for i in range
(end+1)][start:]
def counter_clockwise(start, end):
endless = itertools.cycle(circle)
if end > start:
start = end + (len(circle)-(end
-start))
return [next(endless) for i in range
(start+1)][end:][::-1]
# start < end:
forward=clockwise(1, 6)
b1=counter_clockwise(1, 6)
#start > end:
f1=clockwise(6, 1)
backward=counter_clockwise(6, 1)
print(forward)
print(b1)
print(f1)
print(backward)
输出:
['b', 'c', 'd', 'e', 'f', 'g']
['b', 'a', 'h', 'g']
['g', 'h', 'a', 'b']
['g', 'f', 'e', 'd', 'c', 'b']
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)
也许?
您可以使用 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]
这与您尝试过的有点相似,但是更像 Python 的方式和更通用的方式!
>>> 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']
您可以使用 collections
模块中的 deque
来处理 counter_clockwise
条件的某些部分,例如此示例(您可以根据需要对其进行修改或改进):
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']