2016-05-24 16 views
-3

多くの場合、次のコードによって引き起こされる障害と同様の問題に対処しています。ご覧のとおり、この例で使用した対策は無駄です。何らかの理由で、while len(some_list) > n + 1のように見えますが、最終的には「誤検出」となります。whileループの一般的な失敗:なぜですか?

私はpassステートメントを使用して、この「面白い振る舞い」を無効にすることができます(これはちょっとしたことでもうまくいくと思います)。しかし、ポイントは次のとおりです:なぜこれは実際に起こっていますか?

some_list = [2,3,2] 

some_list.sort(reverse=True) 

n = 0 
while len(some_list) > 1 and n < len(some_list) - 1: 
    try: 
     while len(some_list) > n + 1: 
      # This `if` statement was my last counter-measure 
      if n + 1 >= len(some_list): 
       break 
      while some_list[n] == some_list[n+1]: 
       some_list[n] += some_list.pop(n+1) 
      else: 
       n += 1 
    except: 
     print "WTF!!! len =",len(some_list),", n =",n 
     raise 

これは、コマンドライン上の応答である:

WTF!!! len = 2 , n = 1 
    Traceback (most recent call last): 
    File "example.py", line 11, in <module> 
     while some_list[n] == some_list[n+1]: 
IndexError: list index out of range 

明確化:

  • 私は意図的な目的で、その要素を排除するために.pop()を使用しています。
  • 質問の目的は、この種のエラーの原因を特定することです。
  • このコードは、質問で公開したい例外を引き起こす単なる例です。
  • コードの "目的"は、リストの重複を削除して隣接する要素に追加します(これは等しいと予想されます)。なぜなら間違った推測

    @Kevin Mのグレンジャーによってrecommndedデバッガを使用した後


悪い策定質問:私は自分の愚かさを実現

-> while len(some_list) > n + 1: 
(Pdb) print len(some_list), ">", n + 1 
3 > 2 
(Pdb) next 
> /tmp/kpasa.py(10)<module>() 
-> if n + 1 >= len(some_list): 
(Pdb) print n + 1, ">=", len(some_list) 
2 >= 3 
(Pdb) next 
> /tmp/kpasa.py(13)<module>() 
-> while some_list[n] == some_list[n+1]: 
(Pdb) print len(some_list), n 
3 1 
(Pdb) next 
> /tmp/kpasa.py(14)<module>() 
-> some_list[n] += some_list.pop(n+1) 
(Pdb) next 
> /tmp/kpasa.py(13)<module>() 
-> while some_list[n] == some_list[n+1]: 
(Pdb) print len(some_list), n 
2 1 
(Pdb) next 
IndexError: 'list index out of range' 

。 「偽陽性」は全くありませんでした。 この質問は実際には愚かなです、私はそれを消去する必要があります同意します。

私の無礼と愚かさにはとても残念です。ここ

+2

は、このコードの目的は何であるあなたの予想結果はどのようなものです:

ここで私はあなたが何をしたいのかについて推測しているが、(明確に(少なくとも私には)思わ異なるアプローチですか? – Selcuk

+3

変数とその値を監視しながら、[デバッガ](https://docs.python.org/3/library/pdb.html)を使用してコードをステップバイステップで実行します。 –

+2

また、 'n'がリスト内の最後のインデックス(例では' 1')の次のものと等しいときに発生し、リストの最後の要素をポップします。次に 'n + 1'で参照する要素は? –

答えて

2
while some_list[n] == some_list[n+1]: 
    some_list[n] += some_list.pop(n+1) 

popは、リストの長さを減少させ、そして次のwhile反復でlen(some_list) > n + 1、その例外が発生する可能性があることを保証するものではありません。あなたは、リストのサイズを小さくsome_list[n] += some_list.pop(n+1)ラインで

while len(some_list) > n + 1 and some_list[n] == some_list[n+1]: 
    some_list[n] += some_list.pop(n+1) 
+0

あなたのアプローチでも(btwありがとう)問題を解決しても、なぜ「誤認」が生じるのか疑問は依然としてミステリーです。私はデバッガを試して何が起こるかを見て、答えが見つかるかどうかを確認します。 – SebasSBM

+1

@SebasSBM「偽陽性」はありません。外側の 'while'ループが長さをチェックした後にリストを変更しているので、条件はもはや真です。 – interjay

+0

私はちょうど数時間前に気付いた。私は答えとして証拠を残しました。私はこのことについてあまりにも失礼で、私の過ちは私が長すぎると思ったことを実感しています... – SebasSBM

0

:あなたは、内側にwhileを変更することができます。 while some_list[n] == some_list[n+1]:を次に評価すると、some_list[n+1]は、リストがn + 1要素未満の長さであるため、IndexErrorを発生させます。

1

あなたの悩みはここにある:

while some_list[n] == some_list[n+1]: 
    some_list[n] += some_list.pop(n+1) 

のn = 1、あなたはsome_listのオフ最後の項目をポップして、[1]をsome_listするためにそれを追加します。 "pop"がリストを変更するので、some_listは今や[3、4]になります。次に、some_list [1] == some_list [2]をチェックするwhileの条件に戻りますが、some_listにはインデックス2の項目がなくなります。あなたはちょうどそれを突きつけた。?

some_list = [2,3,2] 

some_list.sort(reverse=True) 

new_list = [] 
prior_value = None 
for old_value in some_list: 
    if old_value == prior_value: 
     new_list[-1] += old_value 
    else: 
     new_list.append(old_value) 
     prior_value = old_value 

print new_list 
+0

これは私が最初に考えたものですが、while len(some_list)> n + 1: 'がTrueを返したため( '2> 2 'はしないでください)...私の実際の混乱があります。 +1努力のために、それは私がより広い視点を持つのを助けました – SebasSBM

関連する問題