6

私が取り組んでいる小さなプロジェクトでは、リストを循環する必要があります。このサイクルの各要素について、前の要素を新しいサイクルの最初の要素として、同じリストを介して別のサイクルを開始する必要があります。たとえば、次のようなものを作成できるようにしたいと考えています。

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

各 .next() の後に itertools.cycle をコピーすると、現在の状態が保存されるため、「外側の」サイクルの要素で新しいサイクルを開始できると考えました。または、「サイクルポインターをリセット」して古い位置に戻すこともできます。私は次のことを試しました:

>>> import itertools, copy
>>> a = itertools.cycle([1, 2, 3, 4])
>>> b = copy.copy(a)

しかし、このエラーが発生しました:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/copy.py", line 95, in copy
    return _reconstruct(x, rv, 0)
  File "/usr/lib/python2.6/copy.py", line 323, in _reconstruct
    y = callable(*args)
  File "/usr/lib/python2.6/copy_reg.py", line 93, in __newobj__
    return cls.__new__(cls, *args)
TypeError: cycle expected 1 arguments, got 0

私が望むものを達成するにはさまざまな方法があることは知っていますが、短くて明確でpythonicなコードを探しています。誰かが別のアイデアやスニペットを持っているかもしれませんか? イテレータ オブジェクトをコピーできないという事実が、私の興味をかき立てました。イテラブルのコピーが必要な状況でのベストプラクティスはありますか? それとも、イテラブルをコピーするのはばかげていて、一般的に役に立たないのでしょうか?

4

1 に答える 1

7

イテラブルのコピーが必要な状況でのベストプラクティスはありますか?

itertools.teeそれぞれがオリジナルと同じアイテムを生成する 2 つのイテレータを提供しますが、オリジナルを取得し、それが生成するすべてを記憶するため、オリジナルはもう使用できません。ただし、MemoryError が発生するまでこれらのサイクルされた値を記憶し続けるため、ここでは役に立ちません。

それとも、イテラブルをコピーするのはばかげていて、一般的に役に立たないのでしょうか?

イテレータは、現在の状態を持ち、アイテムを生成するように定義されています。彼らが将来同じアイテムを生み出すかどうか、または過去にどのアイテムを生み出したかはわかりません。本当のコピーは両方を行わなければならないので、それは不可能です!

あなたの場合、新しいサイクルを作成するのは非常に簡単なので、既存のサイクルをコピーするよりもむしろそれを実行したいと思います。例えば:

def new_cycle( seq, last=None):
    if last is None:
        return cycle(seq)
    else:
        it = cycle(seq)
        while next(it) != last:
            pass
        return it
于 2010-09-30T00:12:08.710 に答える