Итератор кругового списка в Python
Мне нужно перебирать круговой список, возможно, много раз, каждый раз, начиная с последнего посещенного элемента.
прецедент-это пул соединений. Клиент запрашивает соединение, итератор проверяет, доступно ли указанное соединение, и возвращает его, в противном случае циклы до тех пор, пока он не найдет то, что доступно.
есть аккуратный способ сделать это в Python?
6 ответов:
использовать
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'
правильный ответ-использовать itertools.цикл. Но, предположим, что библиотечная функция не существует. Как бы вы это реализовали?
использовать генератор:
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' #....
или вы можете сделать так:
conn = ['a', 'b', 'c', 'c', 'e', 'f'] conn_len = len(conn) index = 0 while True: print(conn[index]) index = (index + 1) % conn_lenпечать Б В Г Д Е А Б... навсегда
вы можете сделать это с
append(pop())петли:l = ['a','b','c','d'] while 1: print l[0] l.append(l.pop(0))или
for i in range()петли:l = ['a','b','c','d'] ll = len(l) while 1: for i in range(ll): print l[i]или просто:
l = ['a','b','c','d'] while 1: 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 1: servers = rotate_servers(servers) print servers[0]
вам нужен пользовательский итератор -- я адаптирую итератор из ответ.
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
Если вы хотите, чтобы цикл
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']
Comments