Python 从增量起始位置创建循环迭代器

Python 从增量起始位置创建循环迭代器,python,python-2.7,loops,offset,Python,Python 2.7,Loops,Offset,我想在索引中创建一个循环迭代器,如下所示 [0,1,2,3,4,5,6,7,8][1,2,3,4,5,6,7,8,0][2,3,4,5,6,7,8,0,1][3,4,5,6,7,8,0,1,2]...[8,0,1,2,3,4,5,6,7] 其中最大值可以是8或其他数字 到目前为止,我有一些代码不起作用 a = ['l','m','n','o','p','q','r','s','t'] #len(a) = 9 b = [[]] *len(a) c = [[]] *len(a) for offse

我想在索引中创建一个循环迭代器,如下所示

[0,1,2,3,4,5,6,7,8][1,2,3,4,5,6,7,8,0][2,3,4,5,6,7,8,0,1][3,4,5,6,7,8,0,1,2]...[8,0,1,2,3,4,5,6,7]
其中最大值可以是8或其他数字

到目前为止,我有一些代码不起作用

a = ['l','m','n','o','p','q','r','s','t'] #len(a) = 9
b = [[]] *len(a)
c = [[]] *len(a)
for offset_index in range(len(a)):
    b[offset_index] = []
    c[offset_index] = []
    for i in range(offset_index, len(a) - offset_index, 1):
        b[offset_index].append(i)
        c[offset_index].append(a[i])
print b
[0,1,2,3,4,5,6,7,8],[1,2,3,4,5,6,7],[2,3,4,5,6],[3,4,5],[4],[],[],[],[],[],[]

我可以看出第二范围函数有问题,但无法想象一个完美的解决方案

这是我的代码:

a = [1, 2, 3, 4, 5]
for slice_index in range(0, len(a)):
    print (a[slice_index::] + a[:slice_index:])
[1,2,3,4,5]
[2,3,4,5,1]
[3,4,5,1,2]
[4,5,1,2,3]
[5,1,2,3,4]

解释:
一个[slice\u index:]
给出数组中索引>=slice\u index的部分。另一个也一样。

itertools.cycle
+
itertools.islice
a = [0,1,2,3,4,5,6,7,8]
b = []
for i in range(len(a)):
    b.append([])
    for j in range(len(a)):
        b[i].append(a[(i+j)%len(a)])

print b
高效的循环和迭代-在编写此解决方案的过程中,没有副本受到损害

from itertools import cycle, islice

l = list(range(9))
repeats = 8

[list(islice(cycle(l), i, len(l) + i)) for i in range(repeats)]

[[0, 1, 2, 3, 4, 5, 6, 7, 8],
 [1, 2, 3, 4, 5, 6, 7, 8, 0],
 [2, 3, 4, 5, 6, 7, 8, 0, 1],
 [3, 4, 5, 6, 7, 8, 0, 1, 2],
 [4, 5, 6, 7, 8, 0, 1, 2, 3],
 [5, 6, 7, 8, 0, 1, 2, 3, 4],
 [6, 7, 8, 0, 1, 2, 3, 4, 5],
 [7, 8, 0, 1, 2, 3, 4, 5, 6]]
或者,如果您不想保留索引:

for i in range(repeats):
    idx = list(islice(cycle(l), i, len(l) + i)) 
    ... # do something with idx

列表理解 寻找性能的用户的选择

[l[i:] + l[:i] for i in range(repeats)]

[[0, 1, 2, 3, 4, 5, 6, 7, 8],
 [1, 2, 3, 4, 5, 6, 7, 8, 0],
 [2, 3, 4, 5, 6, 7, 8, 0, 1],
 [3, 4, 5, 6, 7, 8, 0, 1, 2],
 [4, 5, 6, 7, 8, 0, 1, 2, 3],
 [5, 6, 7, 8, 0, 1, 2, 3, 4],
 [6, 7, 8, 0, 1, 2, 3, 4, 5],
 [7, 8, 0, 1, 2, 3, 4, 5, 6]]
实现,一种类型的

代码

import more_itertools as mit


iterable = range(9)

# Option 1
mit.circular_shifts(iterable)
输出

[(0, 1, 2, 3, 4, 5, 6, 7, 8),
 (1, 2, 3, 4, 5, 6, 7, 8, 0),
 (2, 3, 4, 5, 6, 7, 8, 0, 1),
 (3, 4, 5, 6, 7, 8, 0, 1, 2),
 (4, 5, 6, 7, 8, 0, 1, 2, 3),
 (5, 6, 7, 8, 0, 1, 2, 3, 4),
 (6, 7, 8, 0, 1, 2, 3, 4, 5),
 (7, 8, 0, 1, 2, 3, 4, 5, 6),
 (8, 0, 1, 2, 3, 4, 5, 6, 7)]

备选方案

通过相同的方式使用:


太棒了。谢谢如果我需要为以后保存索引,这是最好的答案。谢谢。@Joylove你的数组大吗?在这种情况下,我的选项1可能比其他答案更有效。我添加了一个不保留索引的版本。检查:)请给你的答案添加一些解释。@AndréKool,它与Dawit的答案相似,但使用了正负指数的混合,而不是模数。将
L[i-j]
替换为
i-j
,以查看生成的索引。
import itertools as it


# Option 2
list(it.islice(mit.windowed(it.cycle(iterable), n=len(iterable)), len(iterable)))

# Option 3
list(mit.windowed(mit.ncycles(iterable, n=2), n=len(iterable)))[:-1]
>>> L = ['a', 'b', 'c', 'd', 'e']
>>> [[L[i-j] for i in range(len(L))] for j in range(len(L), 0, -1)]
[['a', 'b', 'c', 'd', 'e'],
 ['b', 'c', 'd', 'e', 'a'],
 ['c', 'd', 'e', 'a', 'b'],
 ['d', 'e', 'a', 'b', 'c'],
 ['e', 'a', 'b', 'c', 'd']]