Python中的循环列表迭代器

huwehgph  于 2022-12-17  发布在  Python
关注(0)|答案(9)|浏览(163)

我需要迭代循环列表,可能要迭代很多次,每次都从最后访问的项开始。
用例是一个连接池,客户端请求连接,迭代器检查指向的连接是否可用并返回,否则循环直到找到可用的连接。
在Python中我怎样才能做到这一点呢?
如果您需要立即创建一个最大为特定长度的结果列表,而不是按需迭代:有关一般技术,请参见Repeat list to max number of elements;有关Numpy特定技术,请参见How to replicate array to specific length array

63lcw9qa

63lcw9qa1#

使用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'
avwztpqn

avwztpqn2#

正确的答案是使用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'
#....
klh5stk1

klh5stk13#

或者你可以这样做:

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...永远

d6kp6zgx

d6kp6zgx4#

你可以用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]
fhity93d

fhity93d5#

如果你想循环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']
wi3ka0sx

wi3ka0sx6#

您需要一个定制的迭代器--我将改编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
oxosxuxt

oxosxuxt7#

为了避免无限循环,我使用了数组的长度来迭代,直到列表的大小是两倍。你可以实现你自己的前置条件。想法是避免无限循环。

#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
bprjcwpo

bprjcwpo8#

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))
kninwzqo

kninwzqo9#

对于那些可能感兴趣的人。从给定索引开始向前或向后循环:

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))

相关问题