繁体   English   中英

如何以每个循环的+1偏移量无限迭代列表

[英]How to iterate through list infinitely with +1 offset each loop

我想从 0 到结尾无限迭代列表,但是在下一个循环中,我想从 1 开始到结尾加上 0,下一个循环将从 2 开始到结尾加上 0、1,直到最后一个项目,它将从 0 重新开始并走到最后。

这是我的代码:

a = [ 0, 1, 2 ]
offset = 0
rotate = 0

while True:
    print(a[rotate])
    offset += 1
    rotate += 1
    if offset >= len(a):
        offset = 0
        rotate += 1
    if rotate >= len(a):
        rotate = 0

这是我到目前为止提出的解决方案。 它远非完美。

我想要的结果是:

0, 1, 2 # first iteration
1, 2, 0 # second iteration
2, 0, 1 # third iteration
0, 1, 2 # fourth iteration

等等。

您可以使用具有内置且高效的旋转功能 (~O(1)) 的deque

>>> d = deque([0,1,2])
>>> for _ in range(10):
...     print(*d)
...     d.rotate(-1)  # negative -> rotate to the left
...
0 1 2
1 2 0
2 0 1
0 1 2
1 2 0
2 0 1
0 1 2
1 2 0
2 0 1
0 1 2

尝试这个:

a = [0, 1, 2]

while True:
    print(*a, sep=', ')
    a.append(a[0])
    a.pop(0)

输出:

0, 1, 2
1, 2, 0
2, 0, 1
0, 1, 2
1, 2, 0
2, 0, 1
...

或者, pop返回移除的元素,所以可以简化

a = [0, 1, 2]

while True:
    print(*a, sep=', ')
    a.append(a.pop(0))

[感谢 ShadowRanger 和 Tomerikoo 的改进建议。]

您可以使用列表切片创建具有偏移量的列表,然后使用itertools.cycle()无限重复它们。 这仅计算一次所有旋转,然后循环遍历所有旋转:

from itertools import cycle, islice

lst = [0, 1, 2]
items = [lst[i:] + lst[:i] for i in range(len(lst))]
iterator = cycle(items)

for item in islice(iterator, 10):
    print(item)

一旦您通过了预计算,上述方法很快,但您可能(取决于您的用例)更喜欢一种没有前期时间/空间成本的方法。 在这种情况下,您可以改用生成器:

from itertools import cycle, islice

def rotate(lst):
    for offset in cycle(range(len(lst))):
        yield lst[offset:] + lst[:offset]

lst = [0, 1, 2]
for item in islice(rotate(lst), 10):
    print(item)

这两个输出:

[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]

这些代码片段已根据wjandrea的建议进行了改进。

在这里,您还有另一种使用指针的选择:

a = [ 0, 1, 2 ]
i = 0
l = len(a)
while True:
  out = []
  for j in range(i, i+l):
    out.append(a[j%l])
  print(out)
  i=(i+1)%l

输出:

[0, 1, 2]
[1, 2, 0]
[2, 0, 1]
[0, 1, 2]
[1, 2, 0]
[2, 0, 1]

另一种选择,使用列表切片:

cycles = [a[i:]+a[:i] for i, _ in enumerate(a)]
while True:
    for c in cycles: print(c)

或者,如果您不想预先计算cyclesO(n^2)空间,您可以继续重新制作周期:

from itertools import count
n = len(a)
for i in count():
    j = i%n
    print(a[j:]+a[:j])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM