最後に訪問したアイテムから開始するたびに、おそらく何度も循環リストを反復処理する必要があります。
ユースケースは接続プールです。クライアントは接続を要求し、イテレータはポイントされた接続が使用可能かどうかを確認してそれを返します。それ以外の場合は、使用可能な接続が見つかるまでループします。
Pythonでそれを行うためのきちんとした方法はありますか?
最後に訪問したアイテムから開始するたびに、おそらく何度も循環リストを反復処理する必要があります。
ユースケースは接続プールです。クライアントは接続を要求し、イテレータはポイントされた接続が使用可能かどうかを確認してそれを返します。それ以外の場合は、使用可能な接続が見つかるまでループします。
Pythonでそれを行うためのきちんとした方法はありますか?
回答:
を使用してください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 ...
(永遠にループします、明らかに)
イテレータを手動で進め、そこから値を1つずつプルするには、次のように呼び出しますnext(pool)
。
>>> next(pool)
'a'
>>> next(pool)
'b'
pool.next()
して、サイクルから次の単一のアイテムを取得
next(iterator)
(これはBTWもPython 2.xで正常に動作するため、使用するべき正規の形式です)。python 3.0でgenerator.next()が表示されるかを参照してください。より詳細な説明については。それに応じて私の答えを更新しました。
正解は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'
#....
while True
永遠に繰り返す手段
itertools.cycle
より良い答えです。これは、利用できitertools
ない場合に同じ機能を作成する方法を示しています:)
itertools.cycle
しますか?または、単純なジェネレーターはよりメモリ効率の高い設計でしょうか?cycle
ドキュメントごと:Note, this member of the toolkit may require significant auxiliary storage (depending on the length of the iterable).
cycle
、入力イテラブルがlist
ジェネレーターの起動前に変換されることを示唆していますiterable
。
あなたは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.
3つのうち私は関数として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']