Python 中的循环列表迭代器
- 2025-01-20 09:07:00
- admin 原创
- 126
问题描述:
我需要遍历一个循环列表,可能要多次,每次都从最后访问的项目开始。
用例是连接池。客户端请求连接,迭代器检查指向的连接是否可用并返回,否则循环直到找到可用的连接。
我怎样才能在 Python 中巧妙地做到这一点?
如果您需要立即创建一个长度不超过一定的结果列表,而不是按需进行迭代:请参阅将列表重复至最大元素数以了解一般技术,以及请参阅如何将数组复制到特定长度的数组以了解特定于 Numpy 的技术。
解决方案 1:
使用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'
解决方案 2:
正确答案是使用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'
#....
解决方案 3:
你可以这样做:
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...
将永远打印
解决方案 4:
你可以用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]
解决方案 5:
如果您希望循环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']
解决方案 6:
您需要一个自定义迭代器——我将根据这个答案调整迭代器。
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
解决方案 7:
为了避免无限循环,我使用数组的长度进行迭代,直到列表大小增加一倍。您可以实现自己的先决条件。想法是避免无限循环。
#Implement Circular Linked List
from itertools import cycle
list=[1,2,3,4,5]
lstlength=len(list)*2
print(lstlength)
pool=cycle(list)
i=0
#To avoid infinite loop break when you have iterated twice size of the list
for items in pool:
print(items)
if i >lstlength:
break
i += 1
解决方案 8:
class A(object):
def __init__(self, l):
self.strt = 0
self.end = len(l)
self.d = l
def __iter__(self):
return self
def __next__(self):
val = None
if self.strt>=self.end:
self.strt=0
val = self.d[self.strt]
self.strt += 1
return val
a= A([8,9,7,66])
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
解决方案 9:
对于那些可能感兴趣的人。从给定索引开始向前或向后循环:
def loop_fwd(arr, index):
while True:
arr_index = index % len(arr)
yield arr_index, arr[arr_index]
index += 1
def loop_bcw(arr, index):
while True:
arr_index = index % len(arr)
yield arr_index, arr[arr_index]
index -= 1
forward_it = loop_fwd([1,2,3,4,5], 3)
backward_it = loop_bcw([1,2,3,4,5], 3)
print('forward:')
for i in range(10):
print(next(forward_it))
print('backward:')
for i in range(10):
print(next(backward_it))
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD