2015-10-26 4 views
5

私は組み合わせ要素の二つは別の変数tに等しい場合、発見するためにforループを実行している整数のリストを持っています。したがって、t10に等しければ、私はintergerのリストを持っていました: l = [1,2,3,4,5,8,9]の場合、この関数は数字の組み合わせがすべて(1,9),(2,8)のものを出力するはずです。forループが私のリスト内の要素をスキップするのはなぜですか?

私はほとんどが午前感じるが、私は.pop()機能を使用するときに奇妙な何かがリストに起こります。以下のコードは、計算が必要な数字の組み合わせをすべて表示するために使用されていますが、リストの他のすべての要素はスキップされます。ここで

l = [1,2,5,8,13,15,26,38] 
c = 10 
for i in l: 
    first = i 
    l.pop(0) 
    for x in l: 
     second = x 
     print(first,second) 

が出力されます。

1 2 
1 5 
1 8 
1 13 
1 15 
1 26 
1 38 
5 5 
5 8 
5 13 
5 15 
5 26 
5 38 
13 8 
13 13 
13 15 
13 26 
13 38 
26 13 
26 15 
26 26 
26 38 

お知らせ方法2815、そして38がスキップされます。 二forループは元の値を使用することはありませんし、次の反復は、リストの次の要素を反復処理するために行くことができるように、私はl.popを使用しています。何をしようとする

+10

私は確かに、Pythonの専門家ではないんだけど、私は他のオブジェクト指向言語ではそれが一般的にイテレータまたはループ内から反復処理されたコレクションのいずれかを変更するにはかなり悪いアイデアだと考えていることを伝えることができます。私の最初の疑惑はここにあるだろう。あなたはリストからポップアップして、舞台裏でリスト[1]を参照しようとします...リストを変更したので、list [1]は期待どおり2ではなく5になりました。 –

+1

@DavidHoelzerは正しい答えを得たと思います。 –

+0

@AndrewRushton:むしろ人為的な制約です...リストのコピーを反復する方が安全ですが、リスト上で_backwardsを反復すると、現在反復中のリストから要素を安全に削除できます。 BTW '.pop(0)'は、リストを強制的に残りのすべてのリスト要素を強制的にギャップを埋めるように強制するので、むしろ非効率的です。 –

答えて

9

は、あなたがそれを反復しているときにリストを変更しているとして、機能しません。現在の「ポインタ」が最初の要素を指しているとします。今度は最初にポップするので、ポインタは2番目に表示されます。しかし、ループが進むと、ポインタは3番目に移動し、2番目はスキップされます。

リストから組み合わせを探しているようです。あなたの現在のアプローチに

  • 最も近い:代わりにforループ

    while l: 
        first = l.pop(0) 
        for second in l: 
         print(first, second) 
    
  • それとも、だけではなく、リストのインデックスを繰り返す可能性のwhileループを使用して、あなたが試すことができますいくつかの他の方法があります。自分自身:

    for i in range(len(l)): 
        for k in range(i+1, len(l)): 
         print(l[i], l[k]) 
    
  • それとも使用itertools.combinations

    import itertools 
    for first, second in itertools.combinations(l, 2): 
        print(first, second) 
    

しかし、あなたはそれよりも良い行うことができます。あなたはある目標数を加えた数の対を探しているので、目標から最初のものを減算して2番目の数を取得し、その2番目の数字が数字のリストに含まれているかどうかを確認するだけです。 setを使用すると、この検索が一定の時間内に実行され、O(n²)からO(n)への全体的な時間の複雑さが軽減されます。

numbers = set([1,2,5,8,13,15,26,38]) 
target = 10 
for first in numbers: 
    second = target - first 
    if second > first and second in numbers: 
     print(first, second) 
+0

大きな助けをいただきありがとうございます。すべて今働いている –

0

別のアプローチを選択する必要があります。 forループを使用して反復処理をしている間は、リストから要素を削除することはできません。

関連する問題