2013-04-19 22 views
5

コンテナに対して複数の繰り返しを実行する正しい方法は何ですか? Pythonドキュメントから:リストを2回反復する正しい方法はありますか?

イテレータ - (そのようなリストのような)コンテナオブジェクトは、新鮮な新しい イテレータあなたはITER()関数に渡したり、forループ でそれを使用するたびに生成されます。イテレータでこれを試行すると、以前の反復パスで使用された同じイテレータオブジェクト が返され、 は空のコンテナのように見えます。

イテレータのnext()メソッド がStopIterationを呼び出すと、それ以降の呼び出しで引き続きこれが行われることがプロトコルの意図です。 このプロパティに従わない実装は壊れているとみなされます。 (この制約はPython 2.3で追加されました。Pythonの2.2で、様々な イテレータはこのルールに従って分割されます。)

私はこのコードをお持ちの場合:

slist = [1,2,3,4] 
rlist = reversed(slist) 
list(rlist) 
#[4,3,2,1] 
tuple(rlist) 
#() 

最も簡単とどうなりますか'rlist'を2回以上反復する最も正しい方法は?

+4

注意を反復処理する必要があるたびに新しいリバースイテレータを作成することですリストの2倍 - それは簡単です。あなたは実際に '>'を2回繰り返しています。 – mgilson

答えて

7
rlist = list(reversed(slist)) 

次に、必要なだけ頻繁に繰り返します。このトリックはより一般的に適用されます。イテレータを複数回反復する必要があるときはいつでも、それをリストに変換します。

def tosequence(it): 
    """Turn iterable into a sequence, avoiding a copy if possible.""" 
    if not isinstance(it, collections.Sequence): 
     it = list(it) 
    return it 

Sequenceリスト、タプル、多くのカスタムリストのようなオブジェクトの抽象型です。)

+0

なぜテストに気をつけますか?私は 'it = list(it)'がすでにリストになっていれば、それにはコストがかからないと思っていました。そうじゃないの? –

5

私はwouldn:ここで私は、まさにこの目的のために別のプロジェクトにコピー&ペーストを保つコードスニペットですあなたは、私は

slist = [1,2,3,4] 
for element in reversed(slist): 
    print element # do first iteration stuff 
for element in reversed(slist): 
    print element # do second iteration stuff 

ちょうどSLISTでリバースイテレータを設定すると逆に()を考えるだろう、一度反復するためにそれを組み合わせることができない場合は、「tは、二度リストを保存します。逆転は安いです。それが言われているのは、あなたが逆にする必要があるのであれば、私はそれを逆にして、それをそのように保存するだけです。

+1

+1 - '反転(スライス)'を呼び出すと、リスト全体のコピーを作成する 'list(反転(スライス))'よりもはるかに安い新しいイテレータオブジェクトが作成されます。 – Aya

3

コンテナに対して複数の繰り返しを実行する正しい方法は何ですか?

これを2回連続して実行します。問題ない。

「rlist」を2回反復する最も簡単で正確な方法は何でしょうか?

を参照してください、あなたのために働いていない理由はrlistないということである「コンテナ」。

rlist = list(reversed(slist)) # we store the result of the first iteration 
# and then that result can be iterated over multiple times. 

あなたが本当に保存してはならない場合は、次の

list(slist) # another copy of the list 
tuple(slist) # still works! 

だから、簡単な解決策は、あなたが複数回反復する必要がある場合は、項目の実際のコンテナを持っていることを確認する方法を

お知らせ項目は、itertools.teeを試してください。ただし、次のアイテムを開始する前に完全な1つのイテレーションを完了する必要がある場合は、アイテムの格納を実際には避けることはできません。一般的なケースでは、これらの制限の下でのストレージは本当に避けられないものです。

1

元のリストをインプレース(slist.reverse())に戻して何度でも繰り返し、元のリストを元のリストに戻すのはなぜですか?これはあなたのために動作しない場合は

は、逆の順序でリストを反復処理のための最善の解決策は、あなたが反復していない

for _ in xrange(as_many_times_as_i_wish_to_iterate_this_list_in_reverse_order): 
    for x in reversed(slist): 
     do_stuff(x) 
+0

//なぜ、 '_'を変数名として使用しますか?それは何らかの種類の大会ですか? –

+0

私は(他の人がこれをやっているのを見てきました)スローアウェイ値をアンダースコア変数に割り当てます。この方法で私はコードを読んですぐにこの値は関係ないとわかります。 一方、 'gettext'ライブラリは' _() '関数を使用しています...だから、いくつかのコンテキストでは、これはスローアウェイ変数の悪い名前です。 –

関連する問題