Python中的循环列表迭代器

156 投票
9 回答
110555 浏览
提问于 2025-04-18 05:02

我需要遍历一个循环列表,可能会多次遍历,每次都从上次访问的项目开始。

这个场景是关于连接池的。一个客户端请求连接,迭代器检查当前指向的连接是否可用,如果不可用,就循环查找,直到找到一个可用的连接。

我该如何在Python中优雅地实现这个功能呢?


如果你需要的是一个立即生成的结果列表,长度达到一定值,而不是按需遍历:可以查看 将列表重复到最大元素数量 了解一些通用技巧,以及 如何将数组复制到特定长度的数组 了解一些针对Numpy的技巧。

9 个回答

4

如果你想要循环 n 次,可以实现一个叫 ncycles 的功能,这个功能是来自于 itertools 的一个例子

from itertools import chain, repeat


def ncycles(iterable, n):
    "Returns the sequence elements n times"
    return chain.from_iterable(repeat(tuple(iterable), n))


list(ncycles(["a", "b", "c"], 3))
# ['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
5

你可以通过 append(pop()) 循环来实现这个:

l = ['a','b','c','d']
while True:
    print l[0]
    l.append(l.pop(0))

或者使用 for i in range() 循环:

l = ['a','b','c','d']
ll = len(l)
while True:
    for i in range(ll):
       print l[i]

或者简单地:

l = ['a','b','c','d']

while True:
    for i in l:
       print i

以上所有方法都会打印出:

>>>
a
b
c
d
a
b
c
d
...etc.

在这三种方法中,我更倾向于把 append(pop()) 作为一个函数来使用。

servers = ['a','b','c','d']

def rotate_servers(servers):
    servers.append(servers.pop(0))
    return servers

while True:
    servers = rotate_servers(servers)
    print servers[0]
16

你可以这样做:

conn = ['a', 'b', 'c', 'd', 'e', 'f']
conn_len = len(conn)
index = 0
while True:
    print(conn[index])
    index = (index + 1) % conn_len

这样会一直打印出 a b c d e f a b c...,不停地循环下去。

76

正确的做法是使用 itertools.cycle 这个库里的函数。不过,假设这个库的函数不存在,那你该怎么实现呢?

可以使用一个 生成器

def circular():
    while True:
        for connection in ['a', 'b', 'c']:
            yield connection

然后,你可以用 for 循环来无限地遍历,或者你可以调用 next() 来从生成器中获取下一个值:

connections = circular()
next(connections) # 'a'
next(connections) # 'b'
next(connections) # 'c'
next(connections) # 'a'
next(connections) # 'b'
next(connections) # 'c'
next(connections) # 'a'
#....
259

使用 itertools.cycle,这就是它的主要功能:

from itertools import cycle

lst = ['a', 'b', 'c']

pool = cycle(lst)

for item in pool:
    print(item)

输出:

a b c a b c ...

(显然,它会无限循环)


如果你想手动推进迭代器,并一个一个地取出值,只需调用 next(pool)

>>> next(pool)
'a'
>>> next(pool)
'b'

撰写回答