Python中的循环列表迭代器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23416381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Circular list iterator in Python
提问by user443854
I need to iterate over a circular list, possibly many times, each time starting with the last visited item.
我需要遍历一个循环列表,可能多次,每次从最后访问的项目开始。
The use case is a connection pool. A client asks for connection, an iterator checks if pointed-to connection is available and returns it, otherwise loops until it finds one that is available.
用例是连接池。客户端请求连接,迭代器检查指向的连接是否可用并返回它,否则循环直到找到可用的连接。
Is there a neat way to do it in Python?
有没有一种巧妙的方法可以在 Python 中做到这一点?
采纳答案by Lukas Graf
Use itertools.cycle
, that's its exact purpose:
使用itertools.cycle
,这就是它的确切目的:
from itertools import cycle
lst = ['a', 'b', 'c']
pool = cycle(lst)
for item in pool:
print item,
Output:
输出:
a b c a b c ...
(Loops forever, obviously)
(显然,永远循环)
In order to manually advance the iterator and pull values from it one by one, simply call next(pool)
:
为了手动推进迭代器并从中提取值,只需调用next(pool)
:
>>> next(pool)
'a'
>>> next(pool)
'b'
回答by Jacob Krall
The correct answer is to use itertools.cycle. But, let's assume that library function doesn't exist. How would you implement it?
正确答案是使用itertools.cycle。但是,让我们假设库函数不存在。你将如何实施它?
Use a generator:
使用发电机:
def circular():
while True:
for connection in ['a', 'b', 'c']:
yield connection
Then, you can either use a for
statement to iterate infinitely, or you can call next()
to get the single next value from the generator iterator:
然后,您可以使用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'
#....
回答by Ethan Furman
You need a custom iterator -- I'll adapt the iterator from this answer.
您需要一个自定义迭代器——我将从这个答案中调整迭代器。
from itertools import cycle
class ConnectionPool():
def __init__(self, ...):
# whatever is appropriate here to initilize
# your data
self.pool = cycle([blah, blah, etc])
def __iter__(self):
return self
def __next__(self):
for connection in self.pool:
if connection.is_available: # or however you spell it
return connection
回答by viky.pat
Or you can do like this:
或者你可以这样做:
conn = ['a', 'b', 'c', 'd', 'e', 'f']
conn_len = len(conn)
index = 0
while True:
print(conn[index])
index = (index + 1) % conn_len
prints a b c d e f a b c... forever
打印 abcdefab c... 永远
回答by litepresence
you can accomplish this with append(pop())
loop:
你可以用append(pop())
循环来完成这个:
l = ['a','b','c','d']
while 1:
print l[0]
l.append(l.pop(0))
or for i in range()
loop:
或for i in range()
循环:
l = ['a','b','c','d']
ll = len(l)
while 1:
for i in range(ll):
print l[i]
or simply:
或者干脆:
l = ['a','b','c','d']
while 1:
for i in l:
print i
all of which print:
所有这些打印:
>>>
a
b
c
d
a
b
c
d
...etc.
of the three I'd be prone to the append(pop()) approach as a function
在这三个中,我倾向于将 append(pop()) 方法作为函数
servers = ['a','b','c','d']
def rotate_servers(servers):
servers.append(servers.pop(0))
return servers
while 1:
servers = rotate_servers(servers)
print servers[0]
回答by pylang
If you wish to cycle n
times, implement the ncycles
itertools recipe:
如果您希望循环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']