web-dev-qa-db-ja.com

特定の要素から始まるリストを循環します

私がリストを持っているとしましょう:

l = [1, 2, 3, 4]

そして、私はそれを循環したいと思います。通常、それはこのようなことをします、

1, 2, 3, 4, 1, 2, 3, 4, 1, 2...

サイクルの特定の時点で開始できるようにしたいのですが、必ずしもインデックスではありませんが、おそらく要素と一致します。リスト内の任意の要素から始めたいとしましょう==4の場合、出力は次のようになります。

4, 1, 2, 3, 4, 1, 2, 3, 4, 1...

どうすればこれを達成できますか?

19
john

itertools モジュールを見てください。必要なすべての機能を提供します。

from itertools import cycle, islice, dropwhile

L = [1, 2, 3, 4]

cycled = cycle(L)  # cycle thorugh the list 'L'
skipped = dropwhile(lambda x: x != 4, cycled)  # drop the values until x==4
sliced = islice(skipped, None, 10)  # take the first 10 values

result = list(sliced)  # create a list from iterator
print(result)

出力:

[4, 1, 2, 3, 4, 1, 2, 3, 4, 1]
20
ovgolovin

算術mod演算子を使用します。位置kから開始しているとすると、kは次のように更新する必要があります。

_k = (k + 1) % len(l)
_

インデックスではなく特定の要素から開始する場合は、いつでもk = l.index(x)のように検索できます。ここで、xは目的の項目です。

8
0605002

数行で自分でできる場合、私はモジュールをインポートすることはそれほど好きではありません。これがインポートなしの私の解決策です:

def cycle(my_list, start_at=None):
    start_at = 0 if start_at is None else my_list.index(start_at)
    while True:
        yield my_list[start_at]
        start_at = (start_at + 1) % len(my_list)

これにより、リストをループする(無限の)イテレータが返されます。サイクルの次の要素を取得するには、nextステートメントを使用する必要があります。

>>> it1 = cycle([101,102,103,104])
>>> next(it1), next(it1), next(it1), next(it1), next(it1)
(101, 102, 103, 104, 101) # and so on ...
>>> it1 = cycle([101,102,103,104], start_at=103)
>>> next(it1), next(it1), next(it1), next(it1), next(it1)
(103, 104, 101, 102, 103) # and so on ...
3
juliomalegria
import itertools as it
l = [1, 2, 3, 4]
list(it.islice(it.dropwhile(lambda x: x != 4, it.cycle(l)),  10))
# returns: [4, 1, 2, 3, 4, 1, 2, 3, 4, 1]

したがって、必要なイテレータは次のとおりです。

it.dropwhile(lambda x: x != 4, it.cycle(l))
2
eumiro

うーん、 http://docs.python.org/library/itertools.html#itertools.cycle そのような開始要素はありません。

とにかくサイクルを開始して、気に入らない最初の要素を削除するだけかもしれません。

1
user647772

もう1つの奇妙なオプションは、リストの循環を実行できることです後方。例えば:

# Run this once
myList = ['foo', 'bar', 'baz', 'boom']
myItem = 'baz'

# Run this repeatedly to cycle through the list
if myItem in myList:
    myItem = myList[myList.index(myItem)-1]
    print myItem
0
Daniel Klug

次のようなものを使用できます:

def my_cycle(data, start=None):
  k = 0 if not start else start
  while True:
    yield data[k]
    k = (k + 1) % len(data)

次に、以下を実行します。

for val in my_cycle([0,1,2,3], 2):
  print(val)

本質的に前の答えの1つと同じです。私の悪い。

0
stephanmg